library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  3.0.0     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(cowplot)

********************************************************
Note: As of version 1.0.0, cowplot does not change the
  default ggplot2 theme anymore. To recover the previous
  behavior, execute:
  theme_set(theme_cowplot())
********************************************************
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:cowplot’:

    stamp

The following objects are masked from ‘package:dplyr’:

    intersect, setdiff, union

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(mgcv)
Loading required package: nlme

Attaching package: ‘nlme’

The following object is masked from ‘package:dplyr’:

    collapse

This is mgcv 1.8-31. For overview type 'help("mgcv-package")'.
source("UVP_2017_library.R")
Loading required package: future
theme_set(theme_cowplot())
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')

Particles Only

Read In Data

bes<- read_csv("dataOut/binned_EachSize.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
bds <- read_csv("dataOut/binned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
ues <- read_csv("dataOut/unbinned_EachSize.csv")
Parsed with column specification:
cols(
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = ""),
  depth = col_double(),
  psd_gam = col_double(),
  vol = col_double(),
  sizeclass = col_character(),
  lb = col_double(),
  ub = col_double(),
  binsize = col_double(),
  TotalParticles = col_double(),
  nparticles = col_double(),
  n_nparticles = col_double(),
  biovolume = col_double(),
  speed = col_double(),
  flux = col_double(),
  flux_fit = col_double(),
  GamPredictTP = col_double()
)
uds <- read_csv("dataOut/unbinned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
PhoticBase <- 160
OMZBase <- 850

Summary Statistics

PlotNParticles <- uds %>% 
  ggplot(aes(x = tot_nparticles, y = depth, col = profile)) +
 facet_wrap(~project) +
 geom_point(alpha = 0.3, shape = 1) +
scale_y_reverse() + scale_x_log10()

PlotNParticles

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(tot_nparticles~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(tot_nparticles ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

#FSG4 <- gam(tot_nparticles~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   9.0025     0.1091   82.55   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F p-value  
s(depth) 1.1031  1.196 3.873  0.0583 .
s(Day)   1.5509  1.796 3.715  0.0801 .
s(Hour)  0.4267  2.000 0.281  0.2713  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.134   Deviance explained = 17.9%
GCV = 0.76575  Scale est. = 0.71367   n = 60
#summary(FSG2)
#summary(FSG3)
#summary(FSG4)

summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.006778976
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.07324885
summary(FSG3)$r.sq
[1] 0.0542546

But there is between projects:

ProjGam <- gam(tot_nparticles~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)          8.9983     0.4445   20.24   <2e-16 ***
factor(project)P16  17.0001     1.3754   12.36   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
         edf Ref.df     F p-value  
s(depth)   1      1 3.552   0.064 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =    0.7   Deviance explained = 70.9%
GCV = 12.411  Scale est. = 11.855    n = 67
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
#https://stackoverflow.com/questions/30179442/plotting-minor-breaks-on-a-log-scale-with-ggplot
log_breaks = function(maj, radix=10) {
  function(x) {
    minx         = floor(min(logb(x,radix), na.rm=T)) - 1
    maxx         = ceiling(max(logb(x,radix), na.rm=T)) + 1
    n_major      = maxx - minx + 1
    major_breaks = seq(minx, maxx, by=1)
    if (maj) {
      breaks = major_breaks
    } else {
      steps = logb(1:(radix-1),radix)
      breaks = rep(steps, times=n_major) +
               rep(major_breaks, each=radix-1)
    }
    radix^breaks
  }
}
scale_x_log_eng = function(..., radix=10) {
  scale_x_continuous(...,
                     trans=log_trans(radix),
                     breaks=log_breaks(TRUE, radix),
                     minor_breaks=log_breaks(FALSE, radix))
}

#theme_set(theme_bw)
PlotPSDmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = psd, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  labs(y = "Depth (m)", x = "Particle Size Distribution Slope") + 
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

#theme_set(theme_cowplot)

PlotParticlesmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = tot_nparticles, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  scale_x_log10(breaks = c(10, 100, 1000), minor = c(5, 50, 500)) +
  #theme(legend.position = "none") +
  #scale_x_log_eng()+
  labs(y = "Depth (m)", x = "Particles / L") + 
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

# PlotFluxmany <- uds %>% 
#   filter(project == "ETNP") %>%
#   ggplot(aes(x = tot_flux_fit, y = depth, shape = factor(day(time)), fill = hour(time))) +
#  
#   #geom_path(aes(x = psd_gam)) + 
#   #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
#   geom_point(alpha = .6, size = 2, stroke = 1) +
#   scale_y_reverse() + scale_shape_manual(values = c(21:25)) +
#   scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
#   scale_x_log10() + theme(legend.position = "none")



plot_grid(
  PlotParticlesmany,
  PlotPSDmany,
  rel_widths = c(2, 3)
  )
Removed 266 rows containing missing values (geom_point).Removed 266 rows containing missing values (geom_point).

ggsave("figures/ParticlesPSDMany.png")
Saving 12 x 7.41 in image
ggsave("figures/ParticlesPSDMany.svg")
Saving 12 x 7.41 in image
bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(psd~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(psd ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(psd ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG4 <- gam(psd~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01975  -200.6   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.719  1.921 56.605 3.83e-15 ***
s(Day)   1.000  1.000  1.278   0.2631    
s(Hour)  1.547  2.000  2.763   0.0347 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.639   Deviance explained = 66.5%
GCV = 0.025652  Scale est. = 0.023401  n = 60
#summary(FSG2)
#summary(FSG3)
summary(FSG4)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.96083    0.01978  -200.3   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.721  1.922 56.019 4.39e-15 ***
s(Hour)  1.609  2.000  3.023   0.0294 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.638   Deviance explained = 65.9%
GCV = 0.025297  Scale est. = 0.023471  n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.03439091
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.003377312
summary(FSG3)$r.sq
[1] 0.6015425

Not a significant difference in PSD with respect to time.

But there is between projects:

ProjGam <- gam(psd~ s(depth, k = 3) + factor(project), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500))

summary(ProjGam)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + factor(project)

Parametric coefficients:
                   Estimate Std. Error  t value Pr(>|t|)    
(Intercept)        -3.96167    0.02491 -159.029   <2e-16 ***
factor(project)P16 -0.19977    0.07708   -2.592   0.0118 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.224  1.398 34.54 2.26e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.437   Deviance explained = 45.6%
GCV = 0.039117  Scale est. = 0.037234  n = 67

I wonder if I can show that the profiles aren’t statistically significanlty different. Or that they are for that matter… I think in that case, I run a gam with and without a parameter for profile… And then quantify the effect size of that parameter

Or follow this Gavin Simpson Post https://fromthebottomoftheheap.net/2017/10/10/difference-splines-i/

or anova.gam {mgcv}

Calculate gams for each profile, and then run anova.gam to see if they are different…

PlotNParticlesEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = tot_nparticles, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  #geom_path(aes(x = tot_nparticles)) +
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + scale_color_manual(values = c("gray20", "brown")) +
  labs(x = "Particles/L", y = "Depth (m)") +
  theme(legend.position = "none") +
  scale_shape_manual(values = c(1:5)) +
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

PlotNParticlesEP

I removed one outlyer from p16 for visualization purposes (300 particles/l at surface)

PlotPSDEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = psd, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  geom_path(aes(x = psd_gam)) +
  geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_color_manual(values = c("gray20", "brown"))  +
  scale_shape_manual(values = c(1:5)) + labs(y = "", x = "Particle Size Distribution Slope") +
  geom_hline(yintercept = 175, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") 

PlotPSDEP

I may just cow these togther.

plot_grid(PlotNParticlesEP, PlotPSDEP, rel_widths = c(2,3), labels = c("A", "B"))
Removed 1211 rows containing missing values (geom_point).Removed 1211 rows containing missing values (geom_point).Removed 1211 row(s) containing missing values (geom_path).

ggsave("figures/ParticlesAndPSD_ETNPVsP16.svg")
Saving 10 x 4 in image
ggsave("figures/ParticlesAndPSD_ETNPVsP16.png")
Saving 10 x 4 in image
mainParticleComponents <- bds %>%
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  select(project, profile, depth,
         tot_nparticles, small_nparticles, big_nparticles,
         tot_psd = psd, small_psd, big_psd,
         tot_flux_fit, small_flux_fit, big_flux_fit) %>%
  pivot_longer(cols = -c("project", "profile", "depth")) %>%
  separate(name, c("size", "meas")) %>%
  mutate(meas = recode(meas, nparticles = "particles/L")) %>%
  mutate(meas = factor(meas, levels = c("particles/L", "flux", "psd")))
Expected 2 pieces. Additional pieces discarded in 273 rows [7, 8, 9, 16, 17, 18, 25, 26, 27, 34, 35, 36, 43, 44, 45, 52, 53, 54, 61, 62, ...].
PlotFlx <- mainParticleComponents %>% 
  filter(meas != "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size ~ meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + theme(axis.title.x = element_blank(), legend.position = "none", strip.background.y = element_blank(), strip.text.y = element_blank(), plot.margin = unit(c(7,0,7,7), "pt")) + scale_color_manual(values = c("brown", "gray20")) + scale_shape_manual(values = c(1:5)) + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

PlotPSD <- mainParticleComponents %>% 
  filter(meas == "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size~meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank(), axis.line.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), plot.margin = unit(c(7,7,26.5,0), "pt")) +
  scale_color_manual(values = c("brown", "gray20")) +  scale_shape_manual(values = c(1:5)) +  theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = 175, color = "darkgreen")

plot_grid(PlotFlx, PlotPSD, rel_widths = c(3, 2))
Removed 246 rows containing missing values (geom_point).Removed 123 rows containing missing values (geom_point).
ggsave("figures/BigVsSmall.svg")
Saving 7.29 x 4.5 in image
ggsave("figures/BigVsSmall.png")
Saving 7.29 x 4.5 in image

Flux small and flux tot track so closely because ag > psd. since the size distribution of the flux sould be PSD + ag (psd is negative in this case). Yo ucan see the variance at the one depth where psd is flatest at the very top.

eg_dataline <- bds %>% 
  filter(profile == "stn_043", depth == 162.5)
eg_slope =  eg_dataline %>% pull(psd)
eg_icp = eg_dataline %>% pull(icp)
eg_vol = eg_dataline %>% pull(vol)

eg_datablock <- bes %>%
  filter(profile == "stn_043", depth == 162.5)


eg_lb = eg_datablock$lb
eg_binsize = eg_datablock$binsize
eg_nnp = exp(eg_icp + log(eg_lb) * eg_slope)

eg_np = eg_nnp * eg_binsize
eg_tp = eg_np * eg_vol
eg_df <- tibble(lb = eg_lb, n_nparticles = eg_nnp, nparticles = eg_np, TotalParticles = eg_tp)


EgNNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = n_nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Binsize & Volume Normalized \n Particles (#/L/mm)", x = "Size (mm)")

EgNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Normalized Particles" , x = "Size (mm)")

EgTP <- eg_datablock %>%
  ggplot(aes(x = lb, y = TotalParticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs( y = "Total Particles Observed (#)", x = "Size (mm)")

plot_grid(EgNNP, EgTP, labels = c("A", "B"))
Transformation introduced infinite values in continuous y-axisTransformation introduced infinite values in continuous y-axis
ggsave("figures/ExamplePSD163m.png")
Saving 7.29 x 4.5 in image
ggsave("figures/ExamplePSD163m.svg")
Saving 7.29 x 4.5 in image

Smooth flux and um disaggregation.

bds %>% 
  ggplot(aes(y = depth, x = Flux_Smooth, col = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10()

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(Flux_Smooth~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG2 <- gam(Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

FSG3 <- gam(Flux_Smooth ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9312    37.3   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.874  1.984 12.034 0.000111 ***
s(Day)   1.828  1.969  2.774 0.089781 .  
s(Hour)  1.515  2.000  2.784 0.031360 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.333   Deviance explained = 39.2%
GCV = 58.038  Scale est. = 52.024    n = 60
summary(FSG2)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9774   35.53   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.864  1.981 10.835 0.000255 ***
s(Day)   1.737  1.931  1.586 0.243284    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.265   Deviance explained =   31%
GCV = 62.081  Scale est. = 57.32     n = 60
summary(FSG3)

Family: gaussian 
Link function: identity 

Formula:
Flux_Smooth ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  34.7319     0.9944   34.93   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.857  1.979 10.73 0.000277 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.239   Deviance explained = 26.3%
GCV = 62.291  Scale est. = 59.325    n = 60
summary(FSG1)$r.sq - summary(FSG2)$r.sq
[1] 0.06791706
summary(FSG2)$r.sq - summary(FSG3)$r.sq
[1] 0.02571191
summary(FSG3)$r.sq
[1] 0.2392424
bds %>% filter(project == "ETNP") %>% select(profile, depth, Flux_Smooth) %>% pivot_wider(names_from = profile, values_from = Flux_Smooth)

Something is off. All of the flux profiles are identical. Skip this

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
plt1 <- bds %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = DFP, col = factor(time), shape = factor(time))) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(1000, 0)) + xlim(c(0.5, 1.5))+ geom_vline(xintercept = 1) +
   scale_color_manual(values = c(rep("black", 5), rep("blue", 5))) + scale_shape_manual(values = rep(1:5, 2))

plotly::ggplotly(plt1)

What the heck is going on with DFP here. Why is it usually > 1 shouldn’t it be less than 1 when flux is decreasing? This very deep increasing flux seems improbable to me. Lets check the smooths. Or only go to 1000m.

, legend.background = element_blank(), legend.box.background = element_rect()

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
scientific_10_b <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }

scientific_10_c <- function(x) {
    xout <- gsub("1e", "10^{", format(x),fixed=TRUE)
    xout <- gsub("{-0", "{-", xout,fixed=TRUE)
    xout <- gsub("{+", "{", xout,fixed=TRUE)
    xout <- gsub("{0", "{", xout,fixed=TRUE)
    xout <- paste(xout,"}",sep="")
    return(parse(text=xout))
    
}

scale_x_log10nice <- function(name=NULL,omag=seq(-10,20),...) {
    breaks10 <- 10^omag
    scale_x_log10(breaks=breaks10,labels=scientific_10_c(breaks10),...)
}


#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlx <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10nice()+
  #scale_x_log10() + 
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  
  labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  #labs(x = "moo", y = "Depth (m)") +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 20, xmax = 180, ymin = 75, ymax = 500), colour = "red", fill = NA, inherit.aes = FALSE) +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm")) +
   geom_segment(aes(y = 160, yend = 160, x = 20, xend = 500), color = "darkgreen", stroke = 0.5)+
   geom_segment(aes(y = 850, yend = 850, x = 20, xend = 500), color = "darkblue", stroke = 0.5)#+ geom_hline(yintercept = 850, color = "darkblue")
Ignoring unknown parameters: strokeIgnoring unknown parameters: stroke
pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
pltFlxLegend <- get_legend(pltFlx)
Removed 14 rows containing missing values (geom_point).
pltFlx

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxZoom <- bds %>% filter(project == "ETNP" & depth <= 500 & depth >= 75) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse()+
  #scale_x_log10() +
  scale_x_log10(breaks = c(seq(from = 20, to = 50, by = 10), seq(from = 60, to = 180, by = 20)), limits = c(20, 180)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(values = rep(21:25, 2)) + 
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  theme(axis.text.x = element_text(angle = 90)) +
labs(x = "Smoothed Flux", y = "Depth") + theme(legend.position = "none")+
geom_hline(yintercept = 160, color = "darkgreen")

pltFlxZoom

#plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3 <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-2.1, .6), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")+
  geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3

#plotly::ggplotly(plt1pos)
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
# 
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
# 
# pgTop <- plot_grid(pltFlxNoLegend, pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""), label_size = 14)
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
# 
# pgBoth
# 
# ggsave("figures/FluxDeepDive.png")
# ggsave("figures/FluxDeepDive.svg")

Within panel drawing

pgTop <- ggdraw(pltFlxNoLegend 
       ) +
  draw_plot(pltFlxZoom, .4, .25, .55, .60) +
  draw_plot_label(
    c("","B"),
    c(.05, 0.55),
    c(1, 0.85),
    size = 16
  )
Removed 14 rows containing missing values (geom_point).
pgTop

pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c(“C”, ""), label_size = 14)

I don’t know whats going on below here

pgBottom <- pltDelta3  + geom_rect(aes(xmin = -2, xmax = -1.15, ymin = 170, ymax = 1000), colour = "gray50", fill = NA, inherit.aes = FALSE) + draw_plot(pltFlxLegend , -1.9, -575, .7)
pgBoth <- plot_grid(pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    pgBottom + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    ncol = 1, rel_heights = c(4, 4), labels = c("A", "C"), label_size = 16)
Removed 33 rows containing missing values (geom_point).
pgBoth


ggsave("figures/FluxDeepDive.png")
Saving 5 x 9 in image
ggsave("figures/FluxDeepDive.svg")
Saving 5 x 9 in image
# #plot_grid(pltFlxNoLegend, pltFlxZoom, pltDelta3, pltFlxLegend)
# 
# pltFlxLegend <- get_legend(pltFlx + theme(legend.box.margin = margin(0, 0, 40, 10)))
# 
# pgTop <- plot_grid(pltFlxNoLegend + ylim(c(1000, 0)), pltFlxZoom + theme(plot.margin = unit(c(1, 0, 3, 0), units = "cm")), rel_widths = c(2, 1), labels = c("A", "B"))
# pgBottom <- plot_grid(pltDelta3 + ylim(c(1000, 0)), pltFlxLegend , rel_widths = c(3, 1), labels = c("C", ""))
# pgBoth <- plot_grid(pgTop, pgBottom, ncol = 1)
# 
# pgBoth
# 
# #ggsave("figures/FluxShallowDive.png")
# #ggsave("figures/FluxShallowDive.svg")

Test for day to day and hourly variability in delta flux

bdsAddTime <- bds %>% 
  mutate(Hour = hour(time), Day = day(time))

DFG1 <- gam(pracma::nthroot(DF/DZ, 5)~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG2 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG3 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

summary(DFG1)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3) + 
    s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.05697  -3.227  0.00267 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value   
s(depth) 1.716  1.919 4.652 0.03562 * 
s(Day)   1.931  1.995 6.788 0.00412 **
s(Hour)  1.555  2.000 3.247 0.02318 * 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.328   Deviance explained = 41.3%
GCV = 0.15991  Scale est. = 0.1363    n = 42
summary(DFG2)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.06186  -2.972  0.00514 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value  
s(depth) 1.641  1.871 3.599  0.0798 .
s(Day)   1.827  1.970 3.034  0.0463 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.207   Deviance explained = 27.4%
GCV = 0.17984  Scale est. = 0.1607    n = 42
summary(DFG3)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.06635  -2.771  0.00849 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value
s(depth) 1.592  1.834 3.213   0.107

R-sq.(adj) =  0.0878   Deviance explained = 12.3%
GCV = 0.19707  Scale est. = 0.18491   n = 42
summary(DFG1)$r.sq - summary(DFG2)$r.sq
[1] 0.1204131
summary(DFG2)$r.sq - summary(DFG3)$r.sq
[1] 0.1193917
summary(DFG3)$r.sq
[1] 0.08782536

png(filename = “./figures/CombinedP2Info.png”, width = 10, height = 8, units = “in”, res = 200) StationInfoPlot() dev.off()

#plot.new()
FluxGamPlot <- function(){
  par(mfrow = c(2,2))
  plot(DFG1)
  mtext(expression(bold("C")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,1))
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,2))
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
}

FluxGamPlot()

png(filename = "./figures/FluxGamPlot.png", width = 10, height = 8, units = "in", res = 200)
FluxGamPlot()
dev.off()
png 
  2 

Check of actual data for hour

ggplot(data = bds %>% filter(depth >= 175, depth <= 500), aes(y = DF/DZ, x = hour(time), col = depth, group = depth)) + geom_point() + geom_line()

#Osps

(u mol C / m^3 / day)

disagFig <- bds %>% filter(project == "ETNP") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) +
  #labs(x = bquote("Observed - Modeled Small Particle Flux"~(μmol/m^3/day)), y = "Depth (m)") +
  labs(x = paste("OSMS", expression((μmol/m^3/day)))) +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
disagFig

#ggsave("..figures/FluxSizeShift.svg"

 ggsave("figures/FluxSizeShift.png")
Saving 6 x 4 in image
 ggsave("figures/FluxSizeShift.svg")
Saving 6 x 4 in image

Clara Fig

For NSF Proposal plot_grid( PlotParticlesmany, PlotPSDmany, rel_widths = c(2, 3) )


pgTop <- ggdraw(pltFlxNoLegend 
       ) +
  draw_plot(pltFlxZoom, .4, .25, .55, .60) +
  draw_plot_label(
    c("","D"),
    c(.05, 0.55),
    c(1, 0.85),
    size = 16
  )
Removed 14 rows containing missing values (geom_point).
pgCF <- plot_grid(PlotParticlesmany + ylim(c(1000, 0)),
                  PlotPSDmany + ylim(c(1000, 0)) +theme(legend.position = "none"),
                  pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    disagFig + theme(plot.margin = unit(c(0, 0, .2, 0), units = "cm")),
                    ncol = 2, rel_heights = c(4, 4), labels = c("A", "B", "C", "E"), label_size = 16)
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
Removed 308 rows containing missing values (geom_point).Removed 308 rows containing missing values (geom_point).Removed 37 rows containing missing values (geom_point).
pgCF


ggsave("./figures/UVP_for_zoop_proposal.png", pgCF, width = 10, height = 8, units = "in")
bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

OZG1 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG2 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

OZG3 <- gam(ospsDZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 175 & depth <=500 & project == "ETNP"))

summary(OZG1)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.023796   0.002244    10.6 6.42e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F  p-value    
s(depth) 1.9032  1.991 8.166 0.000545 ***
s(Day)   1.8673  1.982 4.932 0.015920 *  
s(Hour)  0.1508  2.000 0.080 0.345843    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.304   Deviance explained = 35.1%
GCV = 0.00032912  Scale est. = 0.00030213  n = 60
summary(OZG2)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.023796   0.002247   10.59 6.54e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.904  1.991 8.157 0.000549 ***
s(Day)   1.868  1.983 4.868 0.016638 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.302   Deviance explained = 34.7%
GCV = 0.00032916  Scale est. = 0.00030298  n = 60
summary(OZG3)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   0.0238     0.0024   9.916 5.03e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.894  1.989 7.458 0.000924 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.204   Deviance explained =   23%
GCV = 0.00036308  Scale est. = 0.00034556  n = 60
summary(OZG1)$r.sq - summary(OZG2)$r.sq
[1] 0.001957736
summary(OZG2)$r.sq - summary(OZG3)$r.sq
[1] 0.09804936
summary(OZG3)$r.sq
[1] 0.2043621
OSMSGamPlot <- function(){
  par(mfrow = c(1,2))
  plot(OZG2)
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,1))
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
}

OSMSGamPlot()

png(filename = "./figures/OSMSGamPlot.png", width = 10, height = 6, units = "in", res = 200)
OSMSGamPlot()

dev.off()
png 
  2 

plot(OZG2)

bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = ospsDZ)) + facet_wrap(~project) + geom_point() + scale_y_reverse(limits = c(500, 0)) + geom_vline(xintercept = 0)

Trap data

trapFlux3 <- read_csv("dataOut/fluxMS_distilled.csv")
Parsed with column specification:
cols(
  Class = col_character(),
  Depth = col_double(),
  TrapID = col_character(),
  TrapType = col_character(),
  SampleType = col_character(),
  C_flux = col_double(),
  C_flux_umol = col_double()
)
UVPFluxComb <- read_csv("dataOut/CombinedProfileFluxEst_DS.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  Flux = col_double()
)
UVPFluxOE <- read_csv("dataOut/ObservedVsExpectedFlux.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  tn_flux = col_double(),
  profile = col_character(),
  project = col_character(),
  time = col_character(),
  tot_flux2 = col_double()
)
trapFlux3
UVPFluxComb

fluxMS_distilled_toPlot <- trapFlux3 %>%
  mutate(SampleType = recode(SampleType, `plus.p` = "plus-particles", top = "top-collector"))
UVPFluxComb %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot) +
  geom_point(aes(x = Flux), size = 3, shape = 21, color = "white", fill = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP")) + # dummy point for the legend
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") + xlab("Flux µmolC/m^2/day") +
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  scale_fill_viridis_d() +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)
 ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
 ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

UVPFluxPlot00 <- UVPFluxComb %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType, ID = TrapID),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot) +
  geom_line(aes(x = Flux), size = 1, color = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP Estimate")) + # dummy point for the legend
  geom_point(aes(x = tot_flux2), size = 3, shape = 21, color = "white", fill = "black", data = UVPFluxOE) +
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") + xlab("Flux µmolC/m^2/day") +
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) 
Ignoring unknown aesthetics: ID
UVPFluxPlot <- UVPFluxPlot00 +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)

UVPFluxPlot

ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

plotly::ggplotly(UVPFluxPlot00)

Low traps 2-14 tc 1-12 tc 1-12 pp 2-17 tc

Example particle size distribution

horizontalGamPlot <- dataGamHorizontal %>% ggplot(aes(x = resp_fit, y = depth, col = log(lb), group = lb)) + scale_y_reverse() + geom_point() + scale_x_log10(limits = c(10^-8, NA)) + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + geom_errorbar(aes(xmin = resp_lower, xmax = resp_upper), width = 10, alpha = 0.5)+ theme_bw()

TPPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = TotalParticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "TotalParticles Observed (#)")

nnpPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = n_nparticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "Binsize and Volume Normalized Particles (#/L/mm)")

FitPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = nnp_smooth, xmin = nnp_lower, xmax = nnp_upper, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "Smoothed - Normalized Particles (#/L/mm)") + geom_errorbar(width = 10, alpha = 0.5)

npLegend <- get_legend(FitPlot + theme(legend.box.margin = margin(0, 0, 40, 200)) + labs(col = expression(log[e](Size (mm)))))
Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).
plot_grid(
  TPPlot + theme(legend.position = "none"),
  nnpPlot + theme(legend.position = "none"),
  npLegend ,
  FitPlot + theme(legend.position = "none")
)
Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).

ggsave("figures/AllParticleSizes.svg")
Saving 10 x 6.18 in image
ggsave("figures/AllParticleSizes.png")
Saving 10 x 6.18 in image

Weber Bianchi Figs

SameGam <- gam(TotalParticles ~s(log(lb), log(depth), by = factor(time)), offset = log(vol * binsize), family = nb(),
    data = bes %>% filter(project == "ETNP"))
besE <- bes %>% filter(project == "ETNP")

lb_new <- exp(seq(from = log(0.1), to = log(2.1), by = 0.05))
ub_new <- lead(lb_new)
binsize_new <- ub_new - lb_new

lbbs <- tibble(lb = lb_new, ub = ub_new, binsize = binsize_new)

Expanded <- expand_grid(lb = exp(seq(from = log(0.1), to = log(2), by = 0.05)), depth = seq(from = 20, to = 2000, by = 20), time = as.factor(unique(besE$time))) %>% left_join(lbbs, by = "lb")

Pred <- exp(predict(SameGam, Expanded))
ToPlot <- bind_cols(Expanded, nnparticles = Pred) %>% mutate(time = as.character(time)) %>% mutate(nparticles = nnparticles * binsize)
ToPlot %>% filter(lb <= 2) %>%  ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c() + scale_y_reverse() + scale_x_log10()  + facet_wrap(~time) + geom_contour(color = "black")

meanBese <- ToPlot %>% filter(lb <= 2) %>% group_by(lb, depth) %>% summarize(nparticles = mean(nparticles), nnparticles = mean(nnparticles))

WBColorMap <- meanBese%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c(name = "log10(number density \n (normalized))") + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept = 850, color = "darkblue")
WBColorMap

Average of everything

#meanBese043 <- ToPlot %>% filter(lb <= 2, time == "2017-01-13 11:51:31")

meanBese%>%
   ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c() + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 160, color = "darkgreen")

Just 043

mbGam <- meanBese %>% group_by(depth)  %>% nest() %>%
  mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% 
  mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))
mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse() + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept =  850, color = "darkblue")

mbGam <- meanBese043 %>% group_by(depth) %>% nest() %>% mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2]))

pWBPSD <- mbGam %>% ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse()  + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept =  850, color = "darkblue")
pWBPSD

Fig 5 WB

bds %>% filter(profile == “stn_043”, depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = “darkgreen”) + geom_hline(yintercept = 950, color = “darkblue”) + geom_ribbon(alpha = 0.2) + labs(x = “PSD slope”)

All of them

bds %>% filter(profile == "stn_043", depth <= 2000) %>% ggplot(aes(x = psd_gam, xmin = psd_gam - psd_seg * 2, xmax = psd_gam + psd_seg * 2, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_ribbon(alpha = 0.2) + labs(x = "PSD slope")

043 only

bds %>% filter(profile == "stn_043", depth <= 2000, depth > 175) %>% ggplot(aes(x = small_biovolume, y = depth)) + geom_path(size = 1) + scale_y_reverse() + geom_hline(yintercept = 175, color = "darkgreen") + geom_hline(yintercept = 950, color = "darkblue") + geom_point()

ubDf0 <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global)
ubDf <- ubDf0 %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
longer object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object lengthlonger object length is not a multiple of shorter object length
ubDf %>% ggplot(aes(x = nbiomass, y = depth , group = time, col = time)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1))

ubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- ubDf %>% filter(depth <= 180, depth >= 160) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
ubDf <- ubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
ubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 175, color = "darkgreen")

Small particles biomass

PubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb < 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- PubDf %>% filter(depth <= 165, depth >= 155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
PubDf <- PubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBS <- PubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1.2)) + geom_hline(yintercept = 160, color = "darkgreen") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 850, color = "darkblue") + labs( x = "Small particle mass (norm.)")
pWBS

LubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb >= 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- LubDf %>% filter(depth <= 165, depth >=155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
LubDf <- LubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBL <- LubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 160, color = "darkgreen") + labs( x = "Large particle mass (norm.)") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = 850, color = "darkblue")
pWBL

For tom and danielle

WBColorMap

pWBPSD

pWBS

pWBL

WBFig5 <- plot_grid(pWBPSD, pWBS,pWBL, nrow = 1, labels = c("B", "C", "D"))
Removed 6 row(s) containing missing values (geom_path).Removed 7 row(s) containing missing values (geom_path).
WBFig5

WBcombined <- plot_grid(WBColorMap + theme(plot.margin = unit(c(0,3,0, 3), "cm")), WBFig5, ncol = 1, labels = c("A", ""))
WBcombined


ggsave("figures/WBModelValidation.png")
Saving 8 x 6 in image

P16 Flux

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxP16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10(limits = c(35, 150),breaks = seq(from = 20, to = 150, by = 20)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  
labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm"))
# 
# 
# 
# pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
# pltFlxLegend <- get_legend(pltFlx)
# 
pltFlxP16

# #plotly::ggplotly(plt1)
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3P16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-1, .1), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  geom_hline(yintercept = 200, color = "darkgreen")+
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3P16

#plotly::ggplotly(plt1pos)
osms_p16 <- bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), group = factor(time))) + geom_point(size = 3) + geom_path() + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + labs(x = "Observed - Modeled Small Particle Flux \n µmol/m^3/day") +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = 175, color = "darkgreen") 
plotly::ggplotly(osms_p16)

#ggsave("..figures/FluxSizeShift.svg"
plot_grid(
  pltFlxP16,
  pltDelta3P16,
  osms_p16
)
Removed 28 rows containing missing values (geom_point).Removed 28 row(s) containing missing values (geom_path).Removed 32 rows containing missing values (geom_point).Removed 32 row(s) containing missing values (geom_path).Removed 29 rows containing missing values (geom_point).Removed 29 row(s) containing missing values (geom_path).

ggsave("figures/P16FluxRelate.svg")
Saving 8 x 8 in image
ggsave("figures/P16FluxRelate.png")
Saving 8 x 8 in image

Flux attenuation example

source("ModelStuff.R")
scan_for_example <- bds %>% filter(project == "ETNP", depth < 500, depth > 200) %>% select(profile, depth, DFP, use_this_DFP, ospsDZ)

loc_station = "stn_036"
loc_depth = 225
loc_prev_depth = loc_depth - 50

loc_DFP <- bds %>% filter(profile == loc_station, depth %in% c(275)) %>% pull(DFP)
loc_use_DFP <- bds %>% filter(profile == loc_station, depth %in% c(275)) %>% pull(use_this_DFP)
for_single_disag <- bes %>% filter(profile == loc_station, depth %in% c(225, 275)) %>% select(depth, lb, nnp_smooth) %>%
  mutate(depth = recode(depth, `225` = "Shallow", `275` = "Deep")) %>%
  pivot_wider(names_from = depth, values_from = nnp_smooth) 

with_disag <- for_single_disag %>%
  mutate(Predicted_Deep = remin_smooth_shuffle(Shallow, loc_use_DFP)) 
#remin_smooth_shuffle(for_single_disag$Shallow,loc_use_DFP)

for_plot_disag <- with_disag %>% pivot_longer(cols = -lb) %>% filter(lb <= 0.5) %>%
  mutate(name = factor(name, levels = c("Shallow", "Deep", "Predicted_Deep"))) %>%
  mutate(name = recode_factor(name, Shallow = "Shallow (250m)", Deep = "Deep (275m)", Predicted_Deep = "Predicted Deep (275m)"))

for_plot_disag %>% ggplot(aes(x = lb, y = value, shape = name)) + geom_point() + scale_x_log10() + scale_y_log10() + scale_shape_manual(values = c(1, 6, 3)) + theme(legend.title = element_blank()) + labs(x = "Particle Size (mm)", y = "Normalized Particle Abundance (#/L/mm)")

ggsave("figures/DisagExample.png")
Saving 7.29 x 4.5 in image
ggsave("figures/DisagExample.svg")
Saving 7.29 x 4.5 in image

EK60

dataBinned <- read_csv("data/backscatter_table_go7.csv")
Parsed with column specification:
cols(
  frequency = col_double(),
  depth_bin = col_double(),
  time_bin = col_datetime(format = ""),
  value = col_double()
)
dataBinned_01 <- dataBinned %>%
  mutate(timeMex = with_tz(time_bin, tzone = "US/Central") )
startDay <- dataBinned_01$timeMex %>% na.omit %>% min %>% floor_date(unit = "days")
endDay <- dataBinned_01$timeMex %>% na.omit %>% max %>% ceiling_date(unit = "days")
timeBreaks <- seq(from = startDay, to = endDay, by = "12 hours")
timeLabels <- format(timeBreaks)
plotLetters <- tribble(
  ~letter, ~depth_bin, ~timeMex,
  "A", 350, as.POSIXct("2017-01-07 13:00:00"),
  "B", 200, as.POSIXct("2017-01-09 23:00:00"),
  "C", 150, as.POSIXct("2017-01-08 13:00:00"),
  "D", 625, as.POSIXct("2017-01-12 07:00:00"),
  "E", 750, as.POSIXct("2017-01-10 02:00:00")
  
)

library(shadowtext)
plot18k <- dataBinned_01 %>% filter(frequency == 18000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") +
  geom_shadowtext(data = plotLetters, aes(x = timeMex - 12 * 60^2, y = depth_bin, label = letter),  inherit.aes = FALSE, size = 6, bg.color = "white", color = "black") +
  geom_segment(data = plotLetters, inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")), color = "white", size = 1.5) + 
  geom_segment(data = plotLetters, inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")))
plot18k


#ggsave("figures/stationP2_EK60_18kOnly.png")
plotLetters <- tribble(
  ~letter, ~depth_bin, ~timeMex,
  "A", 300, as.POSIXct("2017-01-07 13:00:00"),
  "B", 200, as.POSIXct("2017-01-09 23:00:00"),
  "C", 150, as.POSIXct("2017-01-08 13:00:00"),
  "D", 625, as.POSIXct("2017-01-12 07:00:00"),
  "E", 750, as.POSIXct("2017-01-10 02:00:00")
  
)

library(shadowtext)
plot38k <- dataBinned_01 %>% filter(frequency == 38000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -95), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "Day::Hour", y = "Depth (m)", fill = "Backscatter (dB)") + theme_bw()  + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue") +
  geom_shadowtext(data = plotLetters[1:2,], aes(x = timeMex - 12 * 60^2, y = depth_bin, label = letter),  inherit.aes = FALSE, size = 6, bg.color = "white", color = "black") +
  geom_segment(data = plotLetters[1:2,], inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc")), color = "white", size = 1.5) + 
  geom_segment(data = plotLetters[1:2,], inherit.aes = FALSE, aes(x = timeMex - 9 * 60^2, xend = timeMex, y = depth_bin, yend = depth_bin), arrow = arrow(length = unit(0.03, "npc"))) +
  theme(axis.text.x = element_text(size = 12,angle = 90, vjust = 0.5),
        axis.text.y = element_text(size = 12),
        axis.title = element_text(size = 14),
        legend.title = element_text(size = 14)
        )
plot38k

ggsave("figures/stationP2_EK60_38kOnly.png")
Saving 7.29 x 4.5 in image

plot18k + scale_y_reverse(limits = c(500, 200))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.

plot200k <- dataBinned_01 %>% filter(frequency == 200000) %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -155), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + geom_hline(yintercept = 160, color = "darkgreen") +
  geom_hline(yintercept = 850, color = "darkblue")
plot200k

dataBinned_01 %>% ggplot(aes(x = timeMex, y = depth_bin, fill = value)) + geom_tile() + scale_y_reverse() + scale_fill_viridis_c(limits = c(-165, -75), oob = scales::squish) +
  scale_x_datetime(breaks = timeBreaks, date_labels = "%d::%H") + labs(x = "day::hour", y = "depth (m)", fill = "backscatter (dB)") + theme_bw() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  
  
  facet_wrap(~frequency, ncol = 1)


#ggsave("figures/stationP2_EK60_go7.svg", width = 8, height = 20)
#ggsave("figures/stationP2_EK60_go7.png", width = 8, height = 20)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KG1nY3YpCnNvdXJjZSgiVVZQXzIwMTdfbGlicmFyeS5SIikKdGhlbWVfc2V0KHRoZW1lX2Nvd3Bsb3QoKSkKY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKYGBgCgoKIyBQYXJ0aWNsZXMgT25seQoKIyBSZWFkIEluIERhdGEKCmBgYHtyfQpiZXM8LSByZWFkX2NzdigiZGF0YU91dC9iaW5uZWRfRWFjaFNpemUuY3N2IikKYmRzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2Jpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKdWVzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L3VuYmlubmVkX0VhY2hTaXplLmNzdiIpCnVkcyA8LSByZWFkX2NzdigiZGF0YU91dC91bmJpbm5lZF9EZXB0aFN1bW1hcnkuY3N2IikKYGBgCgpgYGB7cn0KUGhvdGljQmFzZSA8LSAxNjAKT01aQmFzZSA8LSA4NTAKYGBgCgoKIyBTdW1tYXJ5IFN0YXRpc3RpY3MKYGBge3J9ClBsb3ROUGFydGljbGVzIDwtIHVkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdG90X25wYXJ0aWNsZXMsIHkgPSBkZXB0aCwgY29sID0gcHJvZmlsZSkpICsKIGZhY2V0X3dyYXAofnByb2plY3QpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjMsIHNoYXBlID0gMSkgKwpzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKQoKUGxvdE5QYXJ0aWNsZXMKYGBgCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgojRlNHNCA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoRlNHMSkKI3N1bW1hcnkoRlNHMikKI3N1bW1hcnkoRlNHMykKI3N1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYAoKQnV0IHRoZXJlIGlzIGJldHdlZW4gcHJvamVjdHM6CmBgYHtyfQpQcm9qR2FtIDwtIGdhbSh0b3RfbnBhcnRpY2xlc34gcyhkZXB0aCwgayA9IDMpICsgZmFjdG9yKHByb2plY3QpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCkpCgpzdW1tYXJ5KFByb2pHYW0pCmBgYAoKYGBge3IgZmlnLndpZHRoID0gMTJ9CmxpYnJhcnkoc2NhbGVzKQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzAxNzk0NDIvcGxvdHRpbmctbWlub3ItYnJlYWtzLW9uLWEtbG9nLXNjYWxlLXdpdGgtZ2dwbG90CmxvZ19icmVha3MgPSBmdW5jdGlvbihtYWosIHJhZGl4PTEwKSB7CiAgZnVuY3Rpb24oeCkgewogICAgbWlueCAgICAgICAgID0gZmxvb3IobWluKGxvZ2IoeCxyYWRpeCksIG5hLnJtPVQpKSAtIDEKICAgIG1heHggICAgICAgICA9IGNlaWxpbmcobWF4KGxvZ2IoeCxyYWRpeCksIG5hLnJtPVQpKSArIDEKICAgIG5fbWFqb3IgICAgICA9IG1heHggLSBtaW54ICsgMQogICAgbWFqb3JfYnJlYWtzID0gc2VxKG1pbngsIG1heHgsIGJ5PTEpCiAgICBpZiAobWFqKSB7CiAgICAgIGJyZWFrcyA9IG1ham9yX2JyZWFrcwogICAgfSBlbHNlIHsKICAgICAgc3RlcHMgPSBsb2diKDE6KHJhZGl4LTEpLHJhZGl4KQogICAgICBicmVha3MgPSByZXAoc3RlcHMsIHRpbWVzPW5fbWFqb3IpICsKICAgICAgICAgICAgICAgcmVwKG1ham9yX2JyZWFrcywgZWFjaD1yYWRpeC0xKQogICAgfQogICAgcmFkaXheYnJlYWtzCiAgfQp9CnNjYWxlX3hfbG9nX2VuZyA9IGZ1bmN0aW9uKC4uLiwgcmFkaXg9MTApIHsKICBzY2FsZV94X2NvbnRpbnVvdXMoLi4uLAogICAgICAgICAgICAgICAgICAgICB0cmFucz1sb2dfdHJhbnMocmFkaXgpLAogICAgICAgICAgICAgICAgICAgICBicmVha3M9bG9nX2JyZWFrcyhUUlVFLCByYWRpeCksCiAgICAgICAgICAgICAgICAgICAgIG1pbm9yX2JyZWFrcz1sb2dfYnJlYWtzKEZBTFNFLCByYWRpeCkpCn0KCiN0aGVtZV9zZXQodGhlbWVfYncpClBsb3RQU0RtYW55IDwtIHVkcyAlPiUgCiAgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSkpKSArCiAKICAjZ2VvbV9wYXRoKGFlcyh4ID0gcHNkX2dhbSkpICsgCiAgI2dlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xLCBvdXRsaW5lX3R5cGUgPSAibG93ZXIiKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsIDApKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBsYWJzKHkgPSAiRGVwdGggKG0pIiwgeCA9ICJQYXJ0aWNsZSBTaXplIERpc3RyaWJ1dGlvbiBTbG9wZSIpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpIAoKI3RoZW1lX3NldCh0aGVtZV9jb3dwbG90KQoKUGxvdFBhcnRpY2xlc21hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHRvdF9ucGFydGljbGVzLCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwogCiAgI2dlb21fcGF0aChhZXMoeCA9IHBzZF9nYW0pKSArIAogICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAuNiwgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMjAwLCAwKSkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKDEwLCAxMDAsIDEwMDApLCBtaW5vciA9IGMoNSwgNTAsIDUwMCkpICsKICAjdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgI3NjYWxlX3hfbG9nX2VuZygpKwogIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlBhcnRpY2xlcyAvIEwiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKCiMgUGxvdEZsdXhtYW55IDwtIHVkcyAlPiUgCiMgICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQojICAgZ2dwbG90KGFlcyh4ID0gdG90X2ZsdXhfZml0LCB5ID0gZGVwdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpKSkgKwojICAKIyAgICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKIyAgICNnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSwgb3V0bGluZV90eXBlID0gImxvd2VyIikgKwojICAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwojICAgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyMToyNSkpICsKIyAgIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKIyAgIHNjYWxlX3hfbG9nMTAoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCgoKcGxvdF9ncmlkKAogIFBsb3RQYXJ0aWNsZXNtYW55LAogIFBsb3RQU0RtYW55LAogIHJlbF93aWR0aHMgPSBjKDIsIDMpCiAgKQoKZ2dzYXZlKCJmaWd1cmVzL1BhcnRpY2xlc1BTRE1hbnkucG5nIikKZ2dzYXZlKCJmaWd1cmVzL1BhcnRpY2xlc1BTRE1hbnkuc3ZnIikKCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKRlNHMSA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0cyIDwtIGdhbShwc2QgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0ocHNkIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHNCA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCiNzdW1tYXJ5KEZTRzIpCiNzdW1tYXJ5KEZTRzMpCnN1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcQpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EKc3VtbWFyeShGU0czKSRyLnNxCmBgYApOb3QgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIFBTRCB3aXRoIHJlc3BlY3QgdG8gdGltZS4KCkJ1dCB0aGVyZSBpcyBiZXR3ZWVuIHByb2plY3RzOgpgYGB7cn0KUHJvakdhbSA8LSBnYW0ocHNkfiBzKGRlcHRoLCBrID0gMykgKyBmYWN0b3IocHJvamVjdCksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwKSkKCnN1bW1hcnkoUHJvakdhbSkKYGBgCgoKCgpJIHdvbmRlciBpZiBJIGNhbiBzaG93IHRoYXQgdGhlIHByb2ZpbGVzIGFyZW4ndCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW5sdHkgZGlmZmVyZW50LiBPciB0aGF0IHRoZXkgYXJlIGZvciB0aGF0IG1hdHRlci4uLgpJIHRoaW5rIGluIHRoYXQgY2FzZSwgSSBydW4gYSBnYW0gd2l0aCBhbmQgd2l0aG91dCBhIHBhcmFtZXRlciBmb3IgcHJvZmlsZS4uLgpBbmQgdGhlbiBxdWFudGlmeSB0aGUgZWZmZWN0IHNpemUgb2YgdGhhdCBwYXJhbWV0ZXIKCk9yIGZvbGxvdyB0aGlzIEdhdmluIFNpbXBzb24gUG9zdApodHRwczovL2Zyb210aGVib3R0b21vZnRoZWhlYXAubmV0LzIwMTcvMTAvMTAvZGlmZmVyZW5jZS1zcGxpbmVzLWkvCgpvciAKYW5vdmEuZ2FtIHttZ2N2fQoKQ2FsY3VsYXRlIGdhbXMgZm9yIGVhY2ggcHJvZmlsZSwgYW5kIHRoZW4gcnVuIGFub3ZhLmdhbSB0byBzZWUgaWYgdGhleSBhcmUgZGlmZmVyZW50Li4uCgpgYGB7cn0KUGxvdE5QYXJ0aWNsZXNFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0b3RfbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArCiBnZW9tX3BvaW50KGFscGhhID0gMC43LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogICNnZW9tX3BhdGgoYWVzKHggPSB0b3RfbnBhcnRpY2xlcykpICsKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEpICsKc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyYXkyMCIsICJicm93biIpKSArCiAgbGFicyh4ID0gIlBhcnRpY2xlcy9MIiwgeSA9ICJEZXB0aCAobSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTo1KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKClBsb3ROUGFydGljbGVzRVAKYGBgCgpJIHJlbW92ZWQgb25lIG91dGx5ZXIgZnJvbSBwMTYgZm9yIHZpc3VhbGl6YXRpb24gcHVycG9zZXMgKDMwMCBwYXJ0aWNsZXMvbCBhdCBzdXJmYWNlKQoKYGBge3J9ClBsb3RQU0RFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwc2QsIHkgPSBkZXB0aCwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKwogZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2l6ZSA9IDIsIHN0cm9rZSA9IDEpICsKICBnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xKSArCnNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJncmF5MjAiLCAiYnJvd24iKSkgICsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArIGxhYnMoeSA9ICIiLCB4ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSAKClBsb3RQU0RFUApgYGAKCkkgbWF5IGp1c3QgY293IHRoZXNlIHRvZ3RoZXIuCgpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDR9CnBsb3RfZ3JpZChQbG90TlBhcnRpY2xlc0VQLCBQbG90UFNERVAsIHJlbF93aWR0aHMgPSBjKDIsMyksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvUGFydGljbGVzQW5kUFNEX0VUTlBWc1AxNi5wbmciKQpgYGAKCmBgYHtyfQptYWluUGFydGljbGVDb21wb25lbnRzIDwtIGJkcyAlPiUKICBmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgc2VsZWN0KHByb2plY3QsIHByb2ZpbGUsIGRlcHRoLAogICAgICAgICB0b3RfbnBhcnRpY2xlcywgc21hbGxfbnBhcnRpY2xlcywgYmlnX25wYXJ0aWNsZXMsCiAgICAgICAgIHRvdF9wc2QgPSBwc2QsIHNtYWxsX3BzZCwgYmlnX3BzZCwKICAgICAgICAgdG90X2ZsdXhfZml0LCBzbWFsbF9mbHV4X2ZpdCwgYmlnX2ZsdXhfZml0KSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKCJwcm9qZWN0IiwgInByb2ZpbGUiLCAiZGVwdGgiKSkgJT4lCiAgc2VwYXJhdGUobmFtZSwgYygic2l6ZSIsICJtZWFzIikpICU+JQogIG11dGF0ZShtZWFzID0gcmVjb2RlKG1lYXMsIG5wYXJ0aWNsZXMgPSAicGFydGljbGVzL0wiKSkgJT4lCiAgbXV0YXRlKG1lYXMgPSBmYWN0b3IobWVhcywgbGV2ZWxzID0gYygicGFydGljbGVzL0wiLCAiZmx1eCIsICJwc2QiKSkpCgpQbG90Rmx4IDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzICE9ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZSB+IG1lYXMsIHNjYWxlcyA9ICJmcmVlX3giKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLmJhY2tncm91bmQueSA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDAsNyw3KSwgInB0IikpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE6NSkpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKQoKUGxvdFBTRCA8LSBtYWluUGFydGljbGVDb21wb25lbnRzICU+JSAKICBmaWx0ZXIobWVhcyA9PSAicHNkIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSB2YWx1ZSwgY29sID0gcHJvamVjdCwgc2hhcGUgPSBwcm9qZWN0KSkgKyBmYWNldF9ncmlkKHNpemV+bWVhcywgc2NhbGVzID0gImZyZWVfeCIpICsgZ2VvbV9wb2ludChzaXplID0gMikgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwgcGxvdC5tYXJnaW4gPSB1bml0KGMoNyw3LDI2LjUsMCksICJwdCIpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJyb3duIiwgImdyYXkyMCIpKSArICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNzUsIGNvbG9yID0gImRhcmtncmVlbiIpCgpwbG90X2dyaWQoUGxvdEZseCwgUGxvdFBTRCwgcmVsX3dpZHRocyA9IGMoMywgMikpCgpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvQmlnVnNTbWFsbC5wbmciKQpgYGAKCkZsdXggc21hbGwgYW5kIGZsdXggdG90IHRyYWNrIHNvIGNsb3NlbHkgYmVjYXVzZSBhZyA+IHBzZC4gc2luY2UgdGhlIHNpemUgZGlzdHJpYnV0aW9uIG9mIHRoZSBmbHV4IHNvdWxkIGJlIFBTRCArIGFnIChwc2QgaXMgbmVnYXRpdmUgaW4gdGhpcyBjYXNlKS4gWW8gdWNhbiBzZWUgdGhlIHZhcmlhbmNlIGF0IHRoZSBvbmUgZGVwdGggd2hlcmUgcHNkIGlzIGZsYXRlc3QgYXQgdGhlIHZlcnkgdG9wLgoKYGBge3J9CmVnX2RhdGFsaW5lIDwtIGJkcyAlPiUgCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKZWdfc2xvcGUgPSAgZWdfZGF0YWxpbmUgJT4lIHB1bGwocHNkKQplZ19pY3AgPSBlZ19kYXRhbGluZSAlPiUgcHVsbChpY3ApCmVnX3ZvbCA9IGVnX2RhdGFsaW5lICU+JSBwdWxsKHZvbCkKCmVnX2RhdGFibG9jayA8LSBiZXMgJT4lCiAgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiLCBkZXB0aCA9PSAxNjIuNSkKCgplZ19sYiA9IGVnX2RhdGFibG9jayRsYgplZ19iaW5zaXplID0gZWdfZGF0YWJsb2NrJGJpbnNpemUKZWdfbm5wID0gZXhwKGVnX2ljcCArIGxvZyhlZ19sYikgKiBlZ19zbG9wZSkKCmVnX25wID0gZWdfbm5wICogZWdfYmluc2l6ZQplZ190cCA9IGVnX25wICogZWdfdm9sCmVnX2RmIDwtIHRpYmJsZShsYiA9IGVnX2xiLCBuX25wYXJ0aWNsZXMgPSBlZ19ubnAsIG5wYXJ0aWNsZXMgPSBlZ19ucCwgVG90YWxQYXJ0aWNsZXMgPSBlZ190cCkKCgpFZ05OUCA8LSBlZ19kYXRhYmxvY2sgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBuX25wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIkJpbnNpemUgJiBWb2x1bWUgTm9ybWFsaXplZCBcbiBQYXJ0aWNsZXMgKCMvTC9tbSkiLCB4ID0gIlNpemUgKG1tKSIpCgpFZ05QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5wYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyh5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGVzIiAsIHggPSAiU2l6ZSAobW0pIikKCkVnVFAgPC0gZWdfZGF0YWJsb2NrICU+JQogIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gVG90YWxQYXJ0aWNsZXMpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIAogIGdlb21fcGF0aChkYXRhID0gZWdfZGYpICsgbGFicyggeSA9ICJUb3RhbCBQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIiwgeCA9ICJTaXplIChtbSkiKQoKcGxvdF9ncmlkKEVnTk5QLCBFZ1RQLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKZ2dzYXZlKCJmaWd1cmVzL0V4YW1wbGVQU0QxNjNtLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9FeGFtcGxlUFNEMTYzbS5zdmciKQoKYGBgCgojIFNtb290aCBmbHV4IGFuZCB1bSBkaXNhZ2dyZWdhdGlvbi4KCmBgYHtyfQpiZHMgJT4lIAogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gRmx1eF9TbW9vdGgsIGNvbCA9IGZhY3Rvcih0aW1lKSkpICsgZmFjZXRfd3JhcCh+cHJvamVjdCkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBzY2FsZV94X2xvZzEwKCkKYGBgCgoKCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShGbHV4X1Ntb290aH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMiA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0oRmx1eF9TbW9vdGggfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMTc1ICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCnN1bW1hcnkoRlNHMikKc3VtbWFyeShGU0czKQoKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0cyKSRyLnNxCnN1bW1hcnkoRlNHMikkci5zcSAtIHN1bW1hcnkoRlNHMykkci5zcQpzdW1tYXJ5KEZTRzMpJHIuc3EKYGBgCgpgYGB7cn0KYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIEZsdXhfU21vb3RoKSAlPiUgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHByb2ZpbGUsIHZhbHVlc19mcm9tID0gRmx1eF9TbW9vdGgpCmBgYAoKU29tZXRoaW5nIGlzIG9mZi4gQWxsIG9mIHRoZSBmbHV4IHByb2ZpbGVzIGFyZSBpZGVudGljYWwuClNraXAgdGhpcwpgYGB7cn0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0MSA8LSBiZHMgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBERlAsIGNvbCA9IGZhY3Rvcih0aW1lKSwgc2hhcGUgPSBmYWN0b3IodGltZSkpKSArIGZhY2V0X3dyYXAofnByb2plY3QpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgeGxpbShjKDAuNSwgMS41KSkrIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsKICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMocmVwKCJibGFjayIsIDUpLCByZXAoImJsdWUiLCA1KSkpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IHJlcCgxOjUsIDIpKQoKcGxvdGx5OjpnZ3Bsb3RseShwbHQxKQpgYGAKCldoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24gd2l0aCBERlAgaGVyZS4gV2h5IGlzIGl0IHVzdWFsbHkgPiAxIHNob3VsZG4ndCBpdCBiZSBsZXNzIHRoYW4gMSB3aGVuIGZsdXggaXMgZGVjcmVhc2luZz8KVGhpcyB2ZXJ5IGRlZXAgaW5jcmVhc2luZyBmbHV4IHNlZW1zIGltcHJvYmFibGUgdG8gbWUuCkxldHMgY2hlY2sgdGhlIHNtb290aHMuIE9yIG9ubHkgZ28gdG8gMTAwMG0uCgosIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpzY2llbnRpZmljXzEwIDwtIGZ1bmN0aW9uKHgpIHtwYXJzZSh0ZXh0PWdzdWIoImVcXCsqIiwgIiAlKiUgMTBeIiwgc2NhbGVzOjpzY2llbnRpZmljX2Zvcm1hdCgpKHgpKSkgfQpzY2llbnRpZmljXzEwX2IgPC0gZnVuY3Rpb24oeCkge3BhcnNlKHRleHQ9Z3N1YigiZVxcKyoiLCAiICUqJSAxMF4iLCBzY2FsZXM6OnNjaWVudGlmaWNfZm9ybWF0KCkoeCkpKSB9CgpzY2llbnRpZmljXzEwX2MgPC0gZnVuY3Rpb24oeCkgewogICAgeG91dCA8LSBnc3ViKCIxZSIsICIxMF57IiwgZm9ybWF0KHgpLGZpeGVkPVRSVUUpCiAgICB4b3V0IDwtIGdzdWIoInstMCIsICJ7LSIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigieysiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigiezAiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gcGFzdGUoeG91dCwifSIsc2VwPSIiKQogICAgcmV0dXJuKHBhcnNlKHRleHQ9eG91dCkpCiAgICAKfQoKc2NhbGVfeF9sb2cxMG5pY2UgPC0gZnVuY3Rpb24obmFtZT1OVUxMLG9tYWc9c2VxKC0xMCwyMCksLi4uKSB7CiAgICBicmVha3MxMCA8LSAxMF5vbWFnCiAgICBzY2FsZV94X2xvZzEwKGJyZWFrcz1icmVha3MxMCxsYWJlbHM9c2NpZW50aWZpY18xMF9jKGJyZWFrczEwKSwuLi4pCn0KCgojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3NjIyODcvaG93LWNhbi1pLWZvcm1hdC1heGlzLWxhYmVscy13aXRoLWV4cG9uZW50cy13aXRoLWdncGxvdDItYW5kLXNjYWxlcwojamFjb2JfbWFnbml0dWRlIDwtIGZ1bmN0aW9uKHgpe2V4cHJlc3Npb24oMTBecm91bmQobG9nMTAoeCkpKX0KCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseCA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9sb2cxMG5pY2UoKSsKICAjc2NhbGVfeF9sb2cxMCgpICsgCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciBvZiBEYXkiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgCiAgbGFicyh4ID0gYnF1b3RlKFNtb290aGVkfkZsdXh+KMK1bW9sfkMvbV4yL2QpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgI2xhYnMoeCA9ICJtb28iLCB5ID0gIkRlcHRoIChtKSIpICsKICBnZW9tX3JlY3QoZGF0YSA9IGRhdGEuZnJhbWUocHJvamVjdCA9ICJFVE5QIiksIGFlcyh4bWluID0gMjAsIHhtYXggPSAxODAsIHltaW4gPSA3NSwgeW1heCA9IDUwMCksIGNvbG91ciA9ICJyZWQiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IC4zKSwgbGVnZW5kLnNwYWNpbmcgPSB1bml0KC4xLCAiY20iKSkgKwogICBnZW9tX3NlZ21lbnQoYWVzKHkgPSAxNjAsIHllbmQgPSAxNjAsIHggPSAyMCwgeGVuZCA9IDUwMCksIGNvbG9yID0gImRhcmtncmVlbiIsIHN0cm9rZSA9IDAuNSkrCiAgIGdlb21fc2VnbWVudChhZXMoeSA9IDg1MCwgeWVuZCA9IDg1MCwgeCA9IDIwLCB4ZW5kID0gNTAwKSwgY29sb3IgPSAiZGFya2JsdWUiLCBzdHJva2UgPSAwLjUpIysgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCgoKCnBsdEZseE5vTGVnZW5kIDwtIHBsdEZseCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKcGx0Rmx4TGVnZW5kIDwtIGdldF9sZWdlbmQocGx0Rmx4KQoKcGx0Rmx4CiNwbG90bHk6OmdncGxvdGx5KHBsdDEpCmBgYAoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKcGx0Rmx4Wm9vbSA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIiAmIGRlcHRoIDw9IDUwMCAmIGRlcHRoID49IDc1KSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IEZsdXhfU21vb3RoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIsIHN0cm9rZSA9IDEpKwogICNnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkrCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKHNlcShmcm9tID0gMjAsIHRvID0gNTAsIGJ5ID0gMTApLCBzZXEoZnJvbSA9IDYwLCB0byA9IDE4MCwgYnkgPSAyMCkpLCBsaW1pdHMgPSBjKDIwLCAxODApKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsKbGFicyh4ID0gIlNtb290aGVkIEZsdXgiLCB5ID0gIkRlcHRoIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwpnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpCgpwbHRGbHhab29tCiNwbG90bHk6OmdncGxvdGx5KHBsdDEpCmBgYAoKCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHREZWx0YTMgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSAjZmlsdGVyKERGUCA+IDEpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gcHJhY21hOjpudGhyb290KERGL0RaLCA1KSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTIuMSwgLjYpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQogICNsYWJzKHggPSAiKERGL0RaKSBeIDEvNSAowrVtb2wgQy9tXjMvZCkgXiAxLzUiKQoKcGx0RGVsdGEzCiNwbG90bHk6OmdncGxvdGx5KHBsdDFwb3MpCmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoID0gOH0KIyAjcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kLCBwbHRGbHhab29tLCBwbHREZWx0YTMsIHBsdEZseExlZ2VuZCkKIyAKIyBwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHggKyB0aGVtZShsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCA0MCwgMTApKSkKIyAKIyBwZ1RvcCA8LSBwbG90X2dyaWQocGx0Rmx4Tm9MZWdlbmQsIHBsdEZseFpvb20gKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLCAwLCAzLCAwKSwgdW5pdHMgPSAiY20iKSksIHJlbF93aWR0aHMgPSBjKDIsIDEpLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSkKIyBwZ0JvdHRvbSA8LSBwbG90X2dyaWQocGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSwgbGFiZWxfc2l6ZSA9IDE0KQojIHBnQm90aCA8LSBwbG90X2dyaWQocGdUb3AsIHBnQm90dG9tLCBuY29sID0gMSkKIyAKIyBwZ0JvdGgKIyAKIyBnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnBuZyIpCiMgZ2dzYXZlKCJmaWd1cmVzL0ZsdXhEZWVwRGl2ZS5zdmciKQoKYGBgCgoKV2l0aGluIHBhbmVsIGRyYXdpbmcKCgpgYGB7ciBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gNX0KcGdUb3AgPC0gZ2dkcmF3KHBsdEZseE5vTGVnZW5kIAogICAgICAgKSArCiAgZHJhd19wbG90KHBsdEZseFpvb20sIC40LCAuMjUsIC41NSwgLjYwKSArCiAgZHJhd19wbG90X2xhYmVsKAogICAgYygiIiwiQiIpLAogICAgYyguMDUsIDAuNTUpLAogICAgYygxLCAwLjg1KSwKICAgIHNpemUgPSAxNgogICkKcGdUb3AKYGBgCnBnQm90dG9tIDwtIHBsb3RfZ3JpZChwbHREZWx0YTMsIHBsdEZseExlZ2VuZCAsIHJlbF93aWR0aHMgPSBjKDMsIDEpLCBsYWJlbHMgPSBjKCJDIiwgIiIpLCBsYWJlbF9zaXplID0gMTQpCgoKCgpJIGRvbid0IGtub3cgd2hhdHMgZ29pbmcgb24gYmVsb3cgaGVyZQoKYGBge3IgZmlnLmhlaWdodCA9IDksIGZpZy53aWR0aCA9IDV9CnBnQm90dG9tIDwtIHBsdERlbHRhMyAgKyBnZW9tX3JlY3QoYWVzKHhtaW4gPSAtMiwgeG1heCA9IC0xLjE1LCB5bWluID0gMTcwLCB5bWF4ID0gMTAwMCksIGNvbG91ciA9ICJncmF5NTAiLCBmaWxsID0gTkEsIGluaGVyaXQuYWVzID0gRkFMU0UpICsgZHJhd19wbG90KHBsdEZseExlZ2VuZCAsIC0xLjksIC01NzUsIC43KQpwZ0JvdGggPC0gcGxvdF9ncmlkKHBnVG9wICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIHBnQm90dG9tICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoNCwgNCksIGxhYmVscyA9IGMoIkEiLCAiQyIpLCBsYWJlbF9zaXplID0gMTYpCnBnQm90aAoKZ2dzYXZlKCJmaWd1cmVzL0ZsdXhEZWVwRGl2ZS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnN2ZyIpCmBgYAoKCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aCA9IDh9CiMgI3Bsb3RfZ3JpZChwbHRGbHhOb0xlZ2VuZCwgcGx0Rmx4Wm9vbSwgcGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQpCiMgCiMgcGx0Rmx4TGVnZW5kIDwtIGdldF9sZWdlbmQocGx0Rmx4ICsgdGhlbWUobGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oMCwgMCwgNDAsIDEwKSkpCiMgCiMgcGdUb3AgPC0gcGxvdF9ncmlkKHBsdEZseE5vTGVnZW5kICsgeWxpbShjKDEwMDAsIDApKSwgcGx0Rmx4Wm9vbSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDEsIDAsIDMsIDApLCB1bml0cyA9ICJjbSIpKSwgcmVsX3dpZHRocyA9IGMoMiwgMSksIGxhYmVscyA9IGMoIkEiLCAiQiIpKQojIHBnQm90dG9tIDwtIHBsb3RfZ3JpZChwbHREZWx0YTMgKyB5bGltKGMoMTAwMCwgMCkpLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSkKIyBwZ0JvdGggPC0gcGxvdF9ncmlkKHBnVG9wLCBwZ0JvdHRvbSwgbmNvbCA9IDEpCiMgCiMgcGdCb3RoCiMgCiMgI2dnc2F2ZSgiZmlndXJlcy9GbHV4U2hhbGxvd0RpdmUucG5nIikKIyAjZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaGFsbG93RGl2ZS5zdmciKQoKYGBgCgpUZXN0IGZvciBkYXkgdG8gZGF5IGFuZCBob3VybHkgdmFyaWFiaWxpdHkgaW4gZGVsdGEgZmx1eApgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lIAogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKREZHMSA8LSBnYW0ocHJhY21hOjpudGhyb290KERGL0RaLCA1KX4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDI1MCAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHMiA8LSBnYW0ocHJhY21hOjpudGhyb290KERGL0RaLCA1KSB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMjUwICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpERkczIDwtIGdhbShwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpIH4gcyhkZXB0aCwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDI1MCAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKc3VtbWFyeShERkcxKQpzdW1tYXJ5KERGRzIpCnN1bW1hcnkoREZHMykKCnN1bW1hcnkoREZHMSkkci5zcSAtIHN1bW1hcnkoREZHMikkci5zcQpzdW1tYXJ5KERGRzIpJHIuc3EgLSBzdW1tYXJ5KERGRzMpJHIuc3EKc3VtbWFyeShERkczKSRyLnNxCmBgYApwbmcoZmlsZW5hbWUgPSAiLi9maWd1cmVzL0NvbWJpbmVkUDJJbmZvLnBuZyIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMjAwKQpTdGF0aW9uSW5mb1Bsb3QoKQpkZXYub2ZmKCkKYGBge3IgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aCA9IDEwfQojcGxvdC5uZXcoKQpGbHV4R2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMiwyKSkKICBwbG90KERGRzEpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJDIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkEiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKICBwYXIobWZnID0gYygxLDIpKQogIG10ZXh0KGV4cHJlc3Npb24oYm9sZCgiQiIpKSwgc2lkZSA9IDMsIGxpbmUgPSAwLCBhZGogPSAwLCBjZXggPSAyKQp9CgpGbHV4R2FtUGxvdCgpCgpwbmcoZmlsZW5hbWUgPSAiLi9maWd1cmVzL0ZsdXhHYW1QbG90LnBuZyIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDgsIHVuaXRzID0gImluIiwgcmVzID0gMjAwKQpGbHV4R2FtUGxvdCgpCmRldi5vZmYoKQpgYGAKCkNoZWNrIG9mIGFjdHVhbCBkYXRhIGZvciBob3VyCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGJkcyAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSwgZGVwdGggPD0gNTAwKSwgYWVzKHkgPSBERi9EWiwgeCA9IGhvdXIodGltZSksIGNvbCA9IGRlcHRoLCBncm91cCA9IGRlcHRoKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX2xpbmUoKQpgYGAKCgojT3NwcwoKKHUgbW9sIEMgLyBtXjMgLyBkYXkpCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA0fQpkaXNhZ0ZpZyA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3Qob3Nwc0RaLCAzKSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBnZW9tX3BvaW50KHNpemUgPSAyKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIDEpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsKICAjbGFicyh4ID0gYnF1b3RlKCJPYnNlcnZlZCAtIE1vZGVsZWQgU21hbGwgUGFydGljbGUgRmx1eCJ+KM68bW9sL21eMy9kYXkpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgbGFicyh4ID0gcGFzdGUoIk9TTVMiLCBleHByZXNzaW9uKCjOvG1vbC9tXjMvZGF5KSkpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpkaXNhZ0ZpZwojZ2dzYXZlKCIuLmZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciCgogZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaXplU2hpZnQucG5nIikKIGdnc2F2ZSgiZmlndXJlcy9GbHV4U2l6ZVNoaWZ0LnN2ZyIpCmBgYAoKIyMjIENsYXJhIEZpZwpGb3IgTlNGIFByb3Bvc2FsCnBsb3RfZ3JpZCgKICBQbG90UGFydGljbGVzbWFueSwKICBQbG90UFNEbWFueSwKICByZWxfd2lkdGhzID0gYygyLCAzKQogICkKYGBge3IgZmlnLmhlaWdodCA9IDgsIGZpZy53aWR0aCA9IDEwfQoKcGdUb3AgPC0gZ2dkcmF3KHBsdEZseE5vTGVnZW5kIAogICAgICAgKSArCiAgZHJhd19wbG90KHBsdEZseFpvb20sIC40LCAuMjUsIC41NSwgLjYwKSArCiAgZHJhd19wbG90X2xhYmVsKAogICAgYygiIiwiRCIpLAogICAgYyguMDUsIDAuNTUpLAogICAgYygxLCAwLjg1KSwKICAgIHNpemUgPSAxNgogICkKCnBnQ0YgPC0gcGxvdF9ncmlkKFBsb3RQYXJ0aWNsZXNtYW55ICsgeWxpbShjKDEwMDAsIDApKSwKICAgICAgICAgICAgICAgICAgUGxvdFBTRG1hbnkgKyB5bGltKGMoMTAwMCwgMCkpICt0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogICAgICAgICAgICAgICAgICBwZ1RvcCArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAsIDAsIDAsIDApLCB1bml0cyA9ICJjbSIpKSwKICAgICAgICAgICAgICAgICAgICBkaXNhZ0ZpZyArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAsIDAsIC4yLCAwKSwgdW5pdHMgPSAiY20iKSksCiAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDIsIHJlbF9oZWlnaHRzID0gYyg0LCA0KSwgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiLCAiRSIpLCBsYWJlbF9zaXplID0gMTYpCnBnQ0YKCmdnc2F2ZSgiLi9maWd1cmVzL1VWUF9mb3Jfem9vcF9wcm9wb3NhbC5wbmciLCBwZ0NGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIpCmBgYAoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKT1pHMSA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSArIHMoSG91ciwgayA9IDQsIGJzID0gImNjIiksIGtub3RzID0gbGlzdChIb3VyID0gYygwLCAyNCkpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDE3NSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKT1pHMiA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCk9aRzMgPC0gZ2FtKG9zcHNEWiB+IHMoZGVwdGgsIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAxNzUgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoT1pHMSkKc3VtbWFyeShPWkcyKQpzdW1tYXJ5KE9aRzMpCgpzdW1tYXJ5KE9aRzEpJHIuc3EgLSBzdW1tYXJ5KE9aRzIpJHIuc3EKc3VtbWFyeShPWkcyKSRyLnNxIC0gc3VtbWFyeShPWkczKSRyLnNxCnN1bW1hcnkoT1pHMykkci5zcQpgYGAKCmBgYHtyfQpPU01TR2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMSwyKSkKICBwbG90KE9aRzIpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJCIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkEiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKfQoKT1NNU0dhbVBsb3QoKQoKcG5nKGZpbGVuYW1lID0gIi4vZmlndXJlcy9PU01TR2FtUGxvdC5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsIHJlcyA9IDIwMCkKT1NNU0dhbVBsb3QoKQoKZGV2Lm9mZigpCmBgYAoKYGBge3J9CnBsb3QoT1pHMikKYGBgCgoKYGBge3J9CmJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIlAxNiIpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gb3Nwc0RaKSkgKyBmYWNldF93cmFwKH5wcm9qZWN0KSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDUwMCwgMCkpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkKYGBgCgojIFRyYXAgZGF0YQpgYGB7cn0KdHJhcEZsdXgzIDwtIHJlYWRfY3N2KCJkYXRhT3V0L2ZsdXhNU19kaXN0aWxsZWQuY3N2IikKVVZQRmx1eENvbWIgPC0gcmVhZF9jc3YoImRhdGFPdXQvQ29tYmluZWRQcm9maWxlRmx1eEVzdF9EUy5jc3YiKQpVVlBGbHV4T0UgPC0gcmVhZF9jc3YoImRhdGFPdXQvT2JzZXJ2ZWRWc0V4cGVjdGVkRmx1eC5jc3YiKQoKYGBgCgpgYGB7cn0KdHJhcEZsdXgzCmBgYApgYGB7cn0KVVZQRmx1eENvbWIKYGBgCgoKYGBge3J9CgpmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdCA8LSB0cmFwRmx1eDMgJT4lCiAgbXV0YXRlKFNhbXBsZVR5cGUgPSByZWNvZGUoU2FtcGxlVHlwZSwgYHBsdXMucGAgPSAicGx1cy1wYXJ0aWNsZXMiLCB0b3AgPSAidG9wLWNvbGxlY3RvciIpKQpgYGAKCmBgYHtyfQpVVlBGbHV4Q29tYiAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCkpICArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjAwKSkgKwogIGdlb21fcG9pbnQoYWVzKHkgPSBEZXB0aCwgeCA9IENfZmx1eF91bW9sLCBmaWxsID0gU2FtcGxlVHlwZSwgc2hhcGUgPSBUcmFwVHlwZSksCiAgICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBzdHJva2UgPSAxLCBzaXplID0gNSwgZGF0YSA9IGZsdXhNU19kaXN0aWxsZWRfdG9QbG90KSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IEZsdXgpLCBzaXplID0gMywgc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiLCBmaWxsID0gImJsYWNrIikgKwogIGdlb21fcG9pbnQoYWVzKHggPSAtMSwgeSA9IC0xLCBzaXplID0gIlVWUCIpKSArICMgZHVtbXkgcG9pbnQgZm9yIHRoZSBsZWdlbmQKc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjUsIDIyKSkrCiAgc2NhbGVfc2l6ZV9tYW51YWwodmFsdWVzID0gMSwgbmFtZSA9ICIiKSArCiAgeWxhYigiRGVwdGggKG0pIikgKyB4bGFiKCJGbHV4IMK1bW9sQy9tXjIvZGF5IikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2hhcGUgPSAyMSkpKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSArCiAgdGhlbWVfY293cGxvdCgpICsgCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjUsIDAuNCksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSksCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMTAsIDUsIDEwLCA1KQogICkgKwogIGdlb21fcmVjdChkYXRhID0gZGF0YS5mcmFtZShwcm9qZWN0ID0gIkVUTlAiKSwgYWVzKHhtaW4gPSAxNSwgeG1heCA9IDMyLCB5bWluID0gNDUsIHltYXggPSAxOTUpLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKQogZ2dzYXZlKCJmaWd1cmVzL0ZpdHRlZEZsdXgucG5nIikKIGdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnN2ZyIpCmBgYAoKYGBge3J9ClVWUEZsdXhQbG90MDAgPC0gVVZQRmx1eENvbWIgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgpKSAgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDIwMCkpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gRGVwdGgsIHggPSBDX2ZsdXhfdW1vbCwgZmlsbCA9IFNhbXBsZVR5cGUsIHNoYXBlID0gVHJhcFR5cGUsIElEID0gVHJhcElEKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIHN0cm9rZSA9IDEsIHNpemUgPSA1LCBkYXRhID0gZmx1eE1TX2Rpc3RpbGxlZF90b1Bsb3QpICsKICBnZW9tX2xpbmUoYWVzKHggPSBGbHV4KSwgc2l6ZSA9IDEsIGNvbG9yID0gImJsYWNrIikgKwogIGdlb21fcG9pbnQoYWVzKHggPSAtMSwgeSA9IC0xLCBzaXplID0gIlVWUCBFc3RpbWF0ZSIpKSArICMgZHVtbXkgcG9pbnQgZm9yIHRoZSBsZWdlbmQKICBnZW9tX3BvaW50KGFlcyh4ID0gdG90X2ZsdXgyKSwgc2l6ZSA9IDMsIHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIiwgZmlsbCA9ICJibGFjayIsIGRhdGEgPSBVVlBGbHV4T0UpICsKc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMjUsIDIyKSkrCiAgc2NhbGVfc2l6ZV9tYW51YWwodmFsdWVzID0gMSwgbmFtZSA9ICIiKSArCiAgeWxhYigiRGVwdGggKG0pIikgKyB4bGFiKCJGbHV4IMK1bW9sQy9tXjIvZGF5IikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2hhcGUgPSAyMSkpKSArCiAgdGhlbWVfY293cGxvdCgpICsgCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjUsIDAuNCksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSksCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMTAsIDUsIDEwLCA1KQogICkgClVWUEZsdXhQbG90IDwtIFVWUEZsdXhQbG90MDAgKwogIGdlb21fcmVjdChkYXRhID0gZGF0YS5mcmFtZShwcm9qZWN0ID0gIkVUTlAiKSwgYWVzKHhtaW4gPSAxNSwgeG1heCA9IDMyLCB5bWluID0gNDUsIHltYXggPSAxOTUpLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKQoKVVZQRmx1eFBsb3QKCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnN2ZyIpCmBgYAoKYGBge3J9CnBsb3RseTo6Z2dwbG90bHkoVVZQRmx1eFBsb3QwMCkKYGBgCkxvdyB0cmFwcyAKMi0xNCB0YwoxLTEyIHRjCjEtMTIgcHAKMi0xNyB0YwoKIyMgRXhhbXBsZSBwYXJ0aWNsZSBzaXplIGRpc3RyaWJ1dGlvbgoKaG9yaXpvbnRhbEdhbVBsb3QgPC0gZGF0YUdhbUhvcml6b250YWwgJT4lIGdncGxvdChhZXMoeCA9IHJlc3BfZml0LCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMChsaW1pdHMgPSBjKDEwXi04LCBOQSkpICsgc2NhbGVfY29sb3JfdmlyaWRpc19jKCkgKyBnZW9tX3BhdGgoKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNSkgICsgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbiA9IHJlc3BfbG93ZXIsIHhtYXggPSByZXNwX3VwcGVyKSwgd2lkdGggPSAxMCwgYWxwaGEgPSAwLjUpKyB0aGVtZV9idygpCgpgYGB7ciBmaWcud2lkdGg9IDEwfQpUUFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IFRvdGFsUGFydGljbGVzLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiVG90YWxQYXJ0aWNsZXMgT2JzZXJ2ZWQgKCMpIikKCm5ucFBsb3QgPC0gYmVzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIpICU+JSBncm91cF9ieShsYikgJT4lIGdncGxvdChhZXMoeCA9IG5fbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBsb2cobGIpLCBncm91cCA9IGxiKSkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKSArIGdlb21fcGF0aCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1KSArIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIkJpbnNpemUgYW5kIFZvbHVtZSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpCgpGaXRQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBubnBfc21vb3RoLCB4bWluID0gbm5wX2xvd2VyLCB4bWF4ID0gbm5wX3VwcGVyLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsgbGFicyh5ID0gIkRlcHRoIChtKSIsIHggPSAiU21vb3RoZWQgLSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpICsgZ2VvbV9lcnJvcmJhcih3aWR0aCA9IDEwLCBhbHBoYSA9IDAuNSkKCm5wTGVnZW5kIDwtIGdldF9sZWdlbmQoRml0UGxvdCArIHRoZW1lKGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDAsIDQwLCAyMDApKSArIGxhYnMoY29sID0gZXhwcmVzc2lvbihsb2dbZV0oU2l6ZSAobW0pKSkpKQoKcGxvdF9ncmlkKAogIFRQUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbm5wUGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbnBMZWdlbmQgLAogIEZpdFBsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCikKCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnBuZyIpCmBgYAoKCiMjIFdlYmVyIEJpYW5jaGkgRmlncwoKCgoKYGBge3J9ClNhbWVHYW0gPC0gZ2FtKFRvdGFsUGFydGljbGVzIH5zKGxvZyhsYiksIGxvZyhkZXB0aCksIGJ5ID0gZmFjdG9yKHRpbWUpKSwgb2Zmc2V0ID0gbG9nKHZvbCAqIGJpbnNpemUpLCBmYW1pbHkgPSBuYigpLAogICAgZGF0YSA9IGJlcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKSkKYGBgCgpgYGB7cn0KYmVzRSA8LSBiZXMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikKCmxiX25ldyA8LSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMi4xKSwgYnkgPSAwLjA1KSkKdWJfbmV3IDwtIGxlYWQobGJfbmV3KQpiaW5zaXplX25ldyA8LSB1Yl9uZXcgLSBsYl9uZXcKCmxiYnMgPC0gdGliYmxlKGxiID0gbGJfbmV3LCB1YiA9IHViX25ldywgYmluc2l6ZSA9IGJpbnNpemVfbmV3KQoKRXhwYW5kZWQgPC0gZXhwYW5kX2dyaWQobGIgPSBleHAoc2VxKGZyb20gPSBsb2coMC4xKSwgdG8gPSBsb2coMiksIGJ5ID0gMC4wNSkpLCBkZXB0aCA9IHNlcShmcm9tID0gMjAsIHRvID0gMjAwMCwgYnkgPSAyMCksIHRpbWUgPSBhcy5mYWN0b3IodW5pcXVlKGJlc0UkdGltZSkpKSAlPiUgbGVmdF9qb2luKGxiYnMsIGJ5ID0gImxiIikKClByZWQgPC0gZXhwKHByZWRpY3QoU2FtZUdhbSwgRXhwYW5kZWQpKQpUb1Bsb3QgPC0gYmluZF9jb2xzKEV4cGFuZGVkLCBubnBhcnRpY2xlcyA9IFByZWQpICU+JSBtdXRhdGUodGltZSA9IGFzLmNoYXJhY3Rlcih0aW1lKSkgJT4lIG11dGF0ZShucGFydGljbGVzID0gbm5wYXJ0aWNsZXMgKiBiaW5zaXplKQpgYGAKCmBgYHtyfQpUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gZGVwdGgsIGZpbGwgPSBsb2cxMChubnBhcnRpY2xlcyksIHogPSBsb2cxMChubnBhcnRpY2xlcykpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9sb2cxMCgpICArIGZhY2V0X3dyYXAofnRpbWUpICsgZ2VvbV9jb250b3VyKGNvbG9yID0gImJsYWNrIikKYGBgCmBgYHtyfQptZWFuQmVzZSA8LSBUb1Bsb3QgJT4lIGZpbHRlcihsYiA8PSAyKSAlPiUgZ3JvdXBfYnkobGIsIGRlcHRoKSAlPiUgc3VtbWFyaXplKG5wYXJ0aWNsZXMgPSBtZWFuKG5wYXJ0aWNsZXMpLCBubnBhcnRpY2xlcyA9IG1lYW4obm5wYXJ0aWNsZXMpKQoKV0JDb2xvck1hcCA8LSBtZWFuQmVzZSU+JQogICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IGRlcHRoLCBmaWxsID0gbG9nMTAobm5wYXJ0aWNsZXMpLCB6ID0gbG9nMTAobm5wYXJ0aWNsZXMpKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hbWUgPSAibG9nMTAobnVtYmVyIGRlbnNpdHkgXG4gKG5vcm1hbGl6ZWQpKSIpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKV0JDb2xvck1hcApgYGAKQXZlcmFnZSBvZiBldmVyeXRoaW5nCgpgYGB7cn0KI21lYW5CZXNlMDQzIDwtIFRvUGxvdCAlPiUgZmlsdGVyKGxiIDw9IDIsIHRpbWUgPT0gIjIwMTctMDEtMTMgMTE6NTE6MzEiKQoKbWVhbkJlc2UlPiUKICAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBkZXB0aCwgZmlsbCA9IGxvZzEwKG5ucGFydGljbGVzKSwgeiA9IGxvZzEwKG5ucGFydGljbGVzKSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX2NvbnRvdXIoY29sb3IgPSAiYmxhY2siKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCkp1c3QgMDQzCgpgYGB7cn0KbWJHYW0gPC0gbWVhbkJlc2UgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIG5lc3QoKSAlPiUKICBtdXRhdGUobW9kID0gbWFwKGRhdGEsIH5nYW0obG9nKG5ucGFydGljbGVzKSB+IGxvZyhsYiksIGZhbWlseSA9IGdhdXNzaWFuKCksIGRhdGEgPSAuKSkpICU+JSAKICBtdXRhdGUocHNkID0gbWFwX2RibChtb2QsIH5zdW1tYXJ5KC4pJHAuY29lZmZbMl0pKQpgYGAKCmBgYHtyfQptYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gIDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKQpgYGAKCgptYkdhbSA8LSBtZWFuQmVzZTA0MyAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgbmVzdCgpICU+JQogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfmdhbShsb2cobm5wYXJ0aWNsZXMpIH4gbG9nKGxiKSwgZmFtaWx5ID0gZ2F1c3NpYW4oKSwgZGF0YSA9IC4pKSkgJT4lIAogIG11dGF0ZShwc2QgPSBtYXBfZGJsKG1vZCwgfnN1bW1hcnkoLikkcC5jb2VmZlsyXSkpCgoKYGBge3J9CnBXQlBTRCA8LSBtYkdhbSAlPiUgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9ICA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKcFdCUFNECmBgYAoKCiMjIEZpZyA1IFdCCgpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQoKQWxsIG9mIHRoZW0KCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCkgJT4lIGdncGxvdChhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gcHNkX3NlZyAqIDIsIHhtYXggPSBwc2RfZ2FtICsgcHNkX3NlZyAqIDIsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcmliYm9uKGFscGhhID0gMC4yKSArIGxhYnMoeCA9ICJQU0Qgc2xvcGUiKQpgYGAKMDQzIG9ubHkKCmBgYHtyfQpiZHMgJT4lIGZpbHRlcihwcm9maWxlID09ICJzdG5fMDQzIiwgZGVwdGggPD0gMjAwMCwgZGVwdGggPiAxNzUpICU+JSBnZ3Bsb3QoYWVzKHggPSBzbWFsbF9iaW92b2x1bWUsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKHNpemUgPSAxKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDk1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQp1YkRmMCA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkKdWJEZiA8LSB1YkRmMCAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGggLCBncm91cCA9IHRpbWUsIGNvbCA9IHRpbWUpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKQpgYGAKCgogCmBgYHtyfQp1YkRmIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKSAlPiUgZ3JvdXBfYnkodGltZSwgZGVwdGgpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBzdW0odWJpb21hc3MpKSAlPiUgdW5ncm91cCAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgc3VtbWFyaXNlKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpCnBob3RpY0Jpb21hc3MgPC0gdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE4MCwgZGVwdGggPj0gMTYwKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQp1YkRmIDwtIHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE3NSwgY29sb3IgPSAiZGFya2dyZWVuIikKYGBgCgoKIyMjIFNtYWxsIHBhcnRpY2xlcyBiaW9tYXNzCgpgYGB7cn0KUHViRGYgPC0gVG9QbG90ICU+JSBtdXRhdGUodWJpb21hc3MgPSBucGFydGljbGVzICogbGIgXiBhZ19nbG9iYWwpICU+JSBmaWx0ZXIobGIgPCAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBQdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE2NSwgZGVwdGggPj0gMTU1KSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gbWVhbih1YmlvbWFzcykpICU+JSBwdWxsKHViaW9tYXNzKQpQdWJEZiA8LSBQdWJEZiAlPiUgbXV0YXRlKG5iaW9tYXNzID0gdWJpb21hc3MvcGhvdGljQmlvbWFzcykKcFdCUyA8LSBQdWJEZiAlPiUgZ2dwbG90KGFlcyh4ID0gbmJpb21hc3MsIHkgPSBkZXB0aCkpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsMS4yKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDg1MCwgY29sb3IgPSAiZGFya2JsdWUiKSArIGxhYnMoIHggPSAiU21hbGwgcGFydGljbGUgbWFzcyAobm9ybS4pIikKcFdCUwpgYGAKCmBgYHtyfQpMdWJEZiA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkgJT4lIGZpbHRlcihsYiA+PSAwLjUpICU+JSBncm91cF9ieSh0aW1lLCBkZXB0aCkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IHN1bSh1YmlvbWFzcykpICU+JSB1bmdyb3VwICU+JSBncm91cF9ieShkZXB0aCkgICU+JSBzdW1tYXJpc2UodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkKcGhvdGljQmlvbWFzcyA8LSBMdWJEZiAlPiUgZmlsdGVyKGRlcHRoIDw9IDE2NSwgZGVwdGggPj0xNTUpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpCkx1YkRmIDwtIEx1YkRmICU+JSBtdXRhdGUobmJpb21hc3MgPSB1YmlvbWFzcy9waG90aWNCaW9tYXNzKQpwV0JMIDwtIEx1YkRmICU+JSBnZ3Bsb3QoYWVzKHggPSBuYmlvbWFzcywgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsgbGFicyggeCA9ICJMYXJnZSBwYXJ0aWNsZSBtYXNzIChub3JtLikiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGNvbG9yID0gImdyYXk1MCIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikKcFdCTApgYGAKCkZvciB0b20gYW5kIGRhbmllbGxlCmBgYHtyfQpXQkNvbG9yTWFwCnBXQlBTRApwV0JTCnBXQkwKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQ9M30KV0JGaWc1IDwtIHBsb3RfZ3JpZChwV0JQU0QsIHBXQlMscFdCTCwgbnJvdyA9IDEsIGxhYmVscyA9IGMoIkIiLCAiQyIsICJEIikpCldCRmlnNQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQgPSA2LCBmaWcud2lkdGggPSA4fQpXQmNvbWJpbmVkIDwtIHBsb3RfZ3JpZChXQkNvbG9yTWFwICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwzLDAsIDMpLCAiY20iKSksIFdCRmlnNSwgbmNvbCA9IDEsIGxhYmVscyA9IGMoIkEiLCAiIikpCldCY29tYmluZWQKCmdnc2F2ZSgiZmlndXJlcy9XQk1vZGVsVmFsaWRhdGlvbi5wbmciKQpgYGAKCiMjIFAxNiBGbHV4IAoKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0Kc2NpZW50aWZpY18xMCA8LSBmdW5jdGlvbih4KSB7cGFyc2UodGV4dD1nc3ViKCJlXFwrKiIsICIgJSolIDEwXiIsIHNjYWxlczo6c2NpZW50aWZpY19mb3JtYXQoKSh4KSkpIH0KI2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNzYyMjg3L2hvdy1jYW4taS1mb3JtYXQtYXhpcy1sYWJlbHMtd2l0aC1leHBvbmVudHMtd2l0aC1nZ3Bsb3QyLWFuZC1zY2FsZXMKI2phY29iX21hZ25pdHVkZSA8LSBmdW5jdGlvbih4KXtleHByZXNzaW9uKDEwXnJvdW5kKGxvZzEwKHgpKSl9CgpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHRGbHhQMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSAgKyBnZW9tX3BvaW50KHNpemUgPSAzLCBzdHJva2UgPSAxKSsKICBnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpKwogIHNjYWxlX3hfbG9nMTAobGltaXRzID0gYygzNSwgMTUwKSxicmVha3MgPSBzZXEoZnJvbSA9IDIwLCB0byA9IDE1MCwgYnkgPSAyMCkpICsKICAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJkYXJrZ3JlZW4iLCBtaWQgPSAiZ3JheTgwIiwgaGlnaCA9ICJwdXJwbGUiLCBtaWRwb2ludCA9IDEwKSArIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICAKbGFicyh4ID0gYnF1b3RlKFNtb290aGVkfkZsdXh+KMK1bW9sfkMvbV4yL2QpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAuMyksIGxlZ2VuZC5zcGFjaW5nID0gdW5pdCguMSwgImNtIikpCiMgCiMgCiMgCiMgcGx0Rmx4Tm9MZWdlbmQgPC0gcGx0Rmx4ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIHBsdEZseExlZ2VuZCA8LSBnZXRfbGVnZW5kKHBsdEZseCkKIyAKcGx0Rmx4UDE2CiMgI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHREZWx0YTNQMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICArIGdlb21fcG9pbnQoc2l6ZSA9IDMsIHN0cm9rZSA9IDEpKwogIGdlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIC4xKSwgYnJlYWtzID0gc2VxKGZyb20gPSAtMiwgdG8gPSAuNzUsIGJ5ID0gMC41KSkgKwogICNzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gImRhcmtncmVlbiIsIG1pZCA9ICJncmF5ODAiLCBoaWdoID0gInB1cnBsZSIsIG1pZHBvaW50ID0gMTApICsgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWUgPSAiRGF5IG9mIE1vbnRoIiwgdmFsdWVzID0gcmVwKDIxOjI1LCAyKSkgKyAKICBzY2FsZV9maWxsX2dyYWRpZW50bihuYW1lID0gIkhvdXIiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgY29sb3IgPSAiZGFya2dyZWVuIikrCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikKICAjbGFicyh4ID0gIihERi9EWikgXiAxLzUgKMK1bW9sIEMvbV4zL2QpIF4gMS81IikKCnBsdERlbHRhM1AxNgojcGxvdGx5OjpnZ3Bsb3RseShwbHQxcG9zKQpgYGAKCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA0fQpvc21zX3AxNiA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJQMTYiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHByYWNtYTo6bnRocm9vdChvc3BzRFosIDMpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICsgZ2VvbV9wb2ludChzaXplID0gMykgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIDEpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgbGFicyh4ID0gIk9ic2VydmVkIC0gTW9kZWxlZCBTbWFsbCBQYXJ0aWNsZSBGbHV4IFxuIMK1bW9sL21eMy9kYXkiKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTc1LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSAKcGxvdGx5OjpnZ3Bsb3RseShvc21zX3AxNikKI2dnc2F2ZSgiLi5maWd1cmVzL0ZsdXhTaXplU2hpZnQuc3ZnIgoKYGBgCgpgYGB7ciBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0PTh9CnBsb3RfZ3JpZCgKICBwbHRGbHhQMTYsCiAgcGx0RGVsdGEzUDE2LAogIG9zbXNfcDE2CikKCmdnc2F2ZSgiZmlndXJlcy9QMTZGbHV4UmVsYXRlLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9QMTZGbHV4UmVsYXRlLnBuZyIpCmBgYAoKIyBGbHV4IGF0dGVudWF0aW9uIGV4YW1wbGUKCmBgYHtyfQpzb3VyY2UoIk1vZGVsU3R1ZmYuUiIpCmBgYAoKCmBgYHtyfQpzY2FuX2Zvcl9leGFtcGxlIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiLCBkZXB0aCA8IDUwMCwgZGVwdGggPiAyMDApICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIERGUCwgdXNlX3RoaXNfREZQLCBvc3BzRFopCgpsb2Nfc3RhdGlvbiA9ICJzdG5fMDM2Igpsb2NfZGVwdGggPSAyMjUKbG9jX3ByZXZfZGVwdGggPSBsb2NfZGVwdGggLSA1MAoKbG9jX0RGUCA8LSBiZHMgJT4lIGZpbHRlcihwcm9maWxlID09IGxvY19zdGF0aW9uLCBkZXB0aCAlaW4lIGMoMjc1KSkgJT4lIHB1bGwoREZQKQpsb2NfdXNlX0RGUCA8LSBiZHMgJT4lIGZpbHRlcihwcm9maWxlID09IGxvY19zdGF0aW9uLCBkZXB0aCAlaW4lIGMoMjc1KSkgJT4lIHB1bGwodXNlX3RoaXNfREZQKQpmb3Jfc2luZ2xlX2Rpc2FnIDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gbG9jX3N0YXRpb24sIGRlcHRoICVpbiUgYygyMjUsIDI3NSkpICU+JSBzZWxlY3QoZGVwdGgsIGxiLCBubnBfc21vb3RoKSAlPiUKICBtdXRhdGUoZGVwdGggPSByZWNvZGUoZGVwdGgsIGAyMjVgID0gIlNoYWxsb3ciLCBgMjc1YCA9ICJEZWVwIikpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBkZXB0aCwgdmFsdWVzX2Zyb20gPSBubnBfc21vb3RoKSAKCndpdGhfZGlzYWcgPC0gZm9yX3NpbmdsZV9kaXNhZyAlPiUKICBtdXRhdGUoUHJlZGljdGVkX0RlZXAgPSByZW1pbl9zbW9vdGhfc2h1ZmZsZShTaGFsbG93LCBsb2NfdXNlX0RGUCkpIAojcmVtaW5fc21vb3RoX3NodWZmbGUoZm9yX3NpbmdsZV9kaXNhZyRTaGFsbG93LGxvY191c2VfREZQKQoKZm9yX3Bsb3RfZGlzYWcgPC0gd2l0aF9kaXNhZyAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtbGIpICU+JSBmaWx0ZXIobGIgPD0gMC41KSAlPiUKICBtdXRhdGUobmFtZSA9IGZhY3RvcihuYW1lLCBsZXZlbHMgPSBjKCJTaGFsbG93IiwgIkRlZXAiLCAiUHJlZGljdGVkX0RlZXAiKSkpICU+JQogIG11dGF0ZShuYW1lID0gcmVjb2RlX2ZhY3RvcihuYW1lLCBTaGFsbG93ID0gIlNoYWxsb3cgKDI1MG0pIiwgRGVlcCA9ICJEZWVwICgyNzVtKSIsIFByZWRpY3RlZF9EZWVwID0gIlByZWRpY3RlZCBEZWVwICgyNzVtKSIpKQoKZm9yX3Bsb3RfZGlzYWcgJT4lIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gdmFsdWUsIHNoYXBlID0gbmFtZSkpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMSwgNiwgMykpICsgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIGxhYnMoeCA9ICJQYXJ0aWNsZSBTaXplIChtbSkiLCB5ID0gIk5vcm1hbGl6ZWQgUGFydGljbGUgQWJ1bmRhbmNlICgjL0wvbW0pIikKCmdnc2F2ZSgiZmlndXJlcy9EaXNhZ0V4YW1wbGUucG5nIikKZ2dzYXZlKCJmaWd1cmVzL0Rpc2FnRXhhbXBsZS5zdmciKQpgYGAKCgojIyBFSzYwCgpgYGB7cn0KZGF0YUJpbm5lZCA8LSByZWFkX2NzdigiZGF0YS9iYWNrc2NhdHRlcl90YWJsZV9nbzcuY3N2IikKYGBgCgpgYGB7cn0KZGF0YUJpbm5lZF8wMSA8LSBkYXRhQmlubmVkICU+JQogIG11dGF0ZSh0aW1lTWV4ID0gd2l0aF90eih0aW1lX2JpbiwgdHpvbmUgPSAiVVMvQ2VudHJhbCIpICkKYGBgCgpgYGB7cn0Kc3RhcnREYXkgPC0gZGF0YUJpbm5lZF8wMSR0aW1lTWV4ICU+JSBuYS5vbWl0ICU+JSBtaW4gJT4lIGZsb29yX2RhdGUodW5pdCA9ICJkYXlzIikKZW5kRGF5IDwtIGRhdGFCaW5uZWRfMDEkdGltZU1leCAlPiUgbmEub21pdCAlPiUgbWF4ICU+JSBjZWlsaW5nX2RhdGUodW5pdCA9ICJkYXlzIikKdGltZUJyZWFrcyA8LSBzZXEoZnJvbSA9IHN0YXJ0RGF5LCB0byA9IGVuZERheSwgYnkgPSAiMTIgaG91cnMiKQp0aW1lTGFiZWxzIDwtIGZvcm1hdCh0aW1lQnJlYWtzKQpgYGAKCgpgYGB7cn0KcGxvdExldHRlcnMgPC0gdHJpYmJsZSgKICB+bGV0dGVyLCB+ZGVwdGhfYmluLCB+dGltZU1leCwKICAiQSIsIDM1MCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0wNyAxMzowMDowMCIpLAogICJCIiwgMjAwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTA5IDIzOjAwOjAwIiksCiAgIkMiLCAxNTAsIGFzLlBPU0lYY3QoIjIwMTctMDEtMDggMTM6MDA6MDAiKSwKICAiRCIsIDYyNSwgYXMuUE9TSVhjdCgiMjAxNy0wMS0xMiAwNzowMDowMCIpLAogICJFIiwgNzUwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTEwIDAyOjAwOjAwIikKICAKKQoKbGlicmFyeShzaGFkb3d0ZXh0KQpwbG90MThrIDwtIGRhdGFCaW5uZWRfMDEgJT4lIGZpbHRlcihmcmVxdWVuY3kgPT0gMTgwMDApICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC03NSksIG9vYiA9IHNjYWxlczo6c3F1aXNoKSArCiAgc2NhbGVfeF9kYXRldGltZShicmVha3MgPSB0aW1lQnJlYWtzLCBkYXRlX2xhYmVscyA9ICIlZDo6JUgiKSArIGxhYnMoeCA9ICJkYXk6OmhvdXIiLCB5ID0gImRlcHRoIChtKSIsIGZpbGwgPSAiYmFja3NjYXR0ZXIgKGRCKSIpICsgdGhlbWVfYncoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxNjAsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4NTAsIGNvbG9yID0gImRhcmtibHVlIikgKwogIGdlb21fc2hhZG93dGV4dChkYXRhID0gcGxvdExldHRlcnMsIGFlcyh4ID0gdGltZU1leCAtIDEyICogNjBeMiwgeSA9IGRlcHRoX2JpbiwgbGFiZWwgPSBsZXR0ZXIpLCAgaW5oZXJpdC5hZXMgPSBGQUxTRSwgc2l6ZSA9IDYsIGJnLmNvbG9yID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwbG90TGV0dGVycywgaW5oZXJpdC5hZXMgPSBGQUxTRSwgYWVzKHggPSB0aW1lTWV4IC0gOSAqIDYwXjIsIHhlbmQgPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCB5ZW5kID0gZGVwdGhfYmluKSwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMDMsICJucGMiKSksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDEuNSkgKyAKICBnZW9tX3NlZ21lbnQoZGF0YSA9IHBsb3RMZXR0ZXJzLCBpbmhlcml0LmFlcyA9IEZBTFNFLCBhZXMoeCA9IHRpbWVNZXggLSA5ICogNjBeMiwgeGVuZCA9IHRpbWVNZXgsIHkgPSBkZXB0aF9iaW4sIHllbmQgPSBkZXB0aF9iaW4pLCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMC4wMywgIm5wYyIpKSkKcGxvdDE4awoKI2dnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF8xOGtPbmx5LnBuZyIpCmBgYAoKYGBge3J9CnBsb3RMZXR0ZXJzIDwtIHRyaWJibGUoCiAgfmxldHRlciwgfmRlcHRoX2JpbiwgfnRpbWVNZXgsCiAgIkEiLCAzMDAsIGFzLlBPU0lYY3QoIjIwMTctMDEtMDcgMTM6MDA6MDAiKSwKICAiQiIsIDIwMCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0wOSAyMzowMDowMCIpLAogICJDIiwgMTUwLCBhcy5QT1NJWGN0KCIyMDE3LTAxLTA4IDEzOjAwOjAwIiksCiAgIkQiLCA2MjUsIGFzLlBPU0lYY3QoIjIwMTctMDEtMTIgMDc6MDA6MDAiKSwKICAiRSIsIDc1MCwgYXMuUE9TSVhjdCgiMjAxNy0wMS0xMCAwMjowMDowMCIpCiAgCikKCmxpYnJhcnkoc2hhZG93dGV4dCkKcGxvdDM4ayA8LSBkYXRhQmlubmVkXzAxICU+JSBmaWx0ZXIoZnJlcXVlbmN5ID09IDM4MDAwKSAlPiUgZ2dwbG90KGFlcyh4ID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgZmlsbCA9IHZhbHVlKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MobGltaXRzID0gYygtMTY1LCAtOTUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiRGF5OjpIb3VyIiwgeSA9ICJEZXB0aCAobSkiLCBmaWxsID0gIkJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsKICBnZW9tX3NoYWRvd3RleHQoZGF0YSA9IHBsb3RMZXR0ZXJzWzE6MixdLCBhZXMoeCA9IHRpbWVNZXggLSAxMiAqIDYwXjIsIHkgPSBkZXB0aF9iaW4sIGxhYmVsID0gbGV0dGVyKSwgIGluaGVyaXQuYWVzID0gRkFMU0UsIHNpemUgPSA2LCBiZy5jb2xvciA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKwogIGdlb21fc2VnbWVudChkYXRhID0gcGxvdExldHRlcnNbMToyLF0sIGluaGVyaXQuYWVzID0gRkFMU0UsIGFlcyh4ID0gdGltZU1leCAtIDkgKiA2MF4yLCB4ZW5kID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgeWVuZCA9IGRlcHRoX2JpbiksIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjAzLCAibnBjIikpLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAxLjUpICsgCiAgZ2VvbV9zZWdtZW50KGRhdGEgPSBwbG90TGV0dGVyc1sxOjIsXSwgaW5oZXJpdC5hZXMgPSBGQUxTRSwgYWVzKHggPSB0aW1lTWV4IC0gOSAqIDYwXjIsIHhlbmQgPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCB5ZW5kID0gZGVwdGhfYmluKSwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMDMsICJucGMiKSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpCiAgICAgICAgKQpwbG90MzhrCgpnZ3NhdmUoImZpZ3VyZXMvc3RhdGlvblAyX0VLNjBfMzhrT25seS5wbmciKQpgYGAKCgpgYGB7cn0KcGxvdDE4ayArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDUwMCwgMjAwKSkKYGBgCgpgYGB7cn0KcGxvdDIwMGsgPC0gZGF0YUJpbm5lZF8wMSAlPiUgZmlsdGVyKGZyZXF1ZW5jeSA9PSAyMDAwMDApICU+JSBnZ3Bsb3QoYWVzKHggPSB0aW1lTWV4LCB5ID0gZGVwdGhfYmluLCBmaWxsID0gdmFsdWUpKSArIGdlb21fdGlsZSgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhsaW1pdHMgPSBjKC0xNjUsIC0xNTUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiZGF5Ojpob3VyIiwgeSA9ICJkZXB0aCAobSkiLCBmaWxsID0gImJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSkpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gODUwLCBjb2xvciA9ICJkYXJrYmx1ZSIpCnBsb3QyMDBrCmBgYAoKYGBge3IgZmlnLmhlaWdodD0yMCwgZmlnLndpZHRoID0gOH0KZGF0YUJpbm5lZF8wMSAlPiUgZ2dwbG90KGFlcyh4ID0gdGltZU1leCwgeSA9IGRlcHRoX2JpbiwgZmlsbCA9IHZhbHVlKSkgKyBnZW9tX3RpbGUoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfZmlsbF92aXJpZGlzX2MobGltaXRzID0gYygtMTY1LCAtNzUpLCBvb2IgPSBzY2FsZXM6OnNxdWlzaCkgKwogIHNjYWxlX3hfZGF0ZXRpbWUoYnJlYWtzID0gdGltZUJyZWFrcywgZGF0ZV9sYWJlbHMgPSAiJWQ6OiVIIikgKyBsYWJzKHggPSAiZGF5Ojpob3VyIiwgeSA9ICJkZXB0aCAobSkiLCBmaWxsID0gImJhY2tzY2F0dGVyIChkQikiKSArIHRoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSkpICsKICAKICAKICBmYWNldF93cmFwKH5mcmVxdWVuY3ksIG5jb2wgPSAxKQoKI2dnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF9nbzcuc3ZnIiwgd2lkdGggPSA4LCBoZWlnaHQgPSAyMCkKI2dnc2F2ZSgiZmlndXJlcy9zdGF0aW9uUDJfRUs2MF9nbzcucG5nIiwgd2lkdGggPSA4LCBoZWlnaHQgPSAyMCkKYGBg